001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/processing/raster/converter/RawData2Image.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2008 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/deegree/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 This library is free software; you can redistribute it and/or 012 modify it under the terms of the GNU Lesser General Public 013 License as published by the Free Software Foundation; either 014 version 2.1 of the License, or (at your option) any later version. 015 016 This library is distributed in the hope that it will be useful, 017 but WITHOUT ANY WARRANTY; without even the implied warranty of 018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 Lesser General Public License for more details. 020 021 You should have received a copy of the GNU Lesser General Public 022 License along with this library; if not, write to the Free Software 023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 024 025 Contact: 026 027 Andreas Poth 028 lat/lon GmbH 029 Aennchenstr. 19 030 53177 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 ---------------------------------------------------------------------------*/ 043 package org.deegree.processing.raster.converter; 044 045 import java.awt.color.ColorSpace; 046 import java.awt.image.BufferedImage; 047 import java.awt.image.ColorModel; 048 import java.awt.image.ComponentColorModel; 049 import java.awt.image.DataBuffer; 050 import java.awt.image.Raster; 051 import java.awt.image.SampleModel; 052 import java.awt.image.WritableRaster; 053 import java.util.Hashtable; 054 055 /** 056 * Offeres methods to wrap raw number data into a <code>BufferedImage</code> 057 * 058 * 059 * @version $Revision: 9346 $ 060 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 061 * @author last edited by: $Author: apoth $ 062 * 063 * @version $Revision: 9346 $, $Date: 2007-12-27 17:39:07 +0100 (Do, 27 Dez 2007) $ 064 */ 065 public class RawData2Image { 066 067 /** 068 * 069 * @param type 070 * the desired DataBuffer type 071 * @param width 072 * @param height 073 * @return a new Image 074 */ 075 private static BufferedImage createImage( int type, int width, int height ) { 076 077 ColorModel ccm = new ComponentColorModel( ColorSpace.getInstance( ColorSpace.CS_GRAY ), null, false, false, 078 BufferedImage.OPAQUE, type ); 079 080 WritableRaster wr = ccm.createCompatibleWritableRaster( width, height ); 081 082 return new BufferedImage( ccm, wr, false, new Hashtable<Object, Object>() ); 083 084 } 085 086 /** 087 * @return result will be a <code>BufferedImage</code> with a GRAY colorspace and 088 * <code>DataBuffer.TYPE_BYTE</code> 089 * 090 * @param data 091 * data to wrap 092 */ 093 public static BufferedImage rawData2Image( byte[][] data ) { 094 095 BufferedImage img = createImage( DataBuffer.TYPE_BYTE, data[0].length, data.length ); 096 Raster raster = img.getData(); 097 DataBuffer buffer = raster.getDataBuffer(); 098 099 for ( int i = 0; i < data.length; i++ ) { 100 for ( int j = 0; j < data[0].length; j++ ) { 101 int pos = data[0].length * i + j; 102 buffer.setElem( pos, data[i][j] ); 103 } 104 } 105 img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) ); 106 return img; 107 } 108 109 /** 110 * @return result will be a <code>BufferedImage</code> with a GRAY colorspace and 111 * <code>DataBuffer.TYPE_USHORT</code> 112 * 113 * @param data 114 * data to wrap 115 */ 116 public static BufferedImage rawData2Image( short[][] data ) { 117 BufferedImage img = createImage( DataBuffer.TYPE_USHORT, data[0].length, data.length ); 118 Raster raster = img.getData(); 119 DataBuffer buffer = raster.getDataBuffer(); 120 121 for ( int i = 0; i < data.length; i++ ) { 122 for ( int j = 0; j < data[0].length; j++ ) { 123 int pos = data[0].length * i + j; 124 buffer.setElem( pos, data[i][j] ); 125 } 126 } 127 img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) ); 128 return img; 129 } 130 131 /** 132 * @return result will be a <code>BufferedImage</code> with a GRAY colorspace and 133 * <code>DataBuffer.TYPE_INT</code> 134 * 135 * @param data 136 * data to wrap 137 */ 138 public static BufferedImage rawData2Image( int[][] data ) { 139 BufferedImage img = createImage( DataBuffer.TYPE_INT, data[0].length, data.length ); 140 Raster raster = img.getData(); 141 DataBuffer buffer = raster.getDataBuffer(); 142 143 for ( int i = 0; i < data.length; i++ ) { 144 for ( int j = 0; j < data[0].length; j++ ) { 145 int pos = data[0].length * i + j; 146 buffer.setElem( pos, data[i][j] ); 147 } 148 } 149 img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) ); 150 return img; 151 } 152 153 /** 154 * Float data requires 4 Byte (32Bit) per data cell. It is common to reduce data depth by 155 * multiplying float values with 10 and map the rounded result to an unsigned short value 156 * (16Bit). This behavior can be controlled by the second parameter passed to this method. If 157 * set to <code>true</code> a image with 32Bit data depth and INT Databuffer will be created. 158 * Otherwise a 16Bit Image with an USHORT Databuffer will be created.<br> 159 * A default scale of 10 and no offset will be used 160 * 161 * @return result will be a <code>BufferedImage</code> with a GRAY colorspace. 162 * 163 * @param data 164 * data to wrap 165 * @param use32Bits 166 */ 167 public static BufferedImage rawData2Image( float[][] data, boolean use32Bits ) { 168 return rawData2Image( data, use32Bits, 10, 0 ); 169 } 170 171 /** 172 * Float data requires 4 Byte (32Bit) per data cell. It is common to reduce data depth by 173 * multiplying float values with 10 and map the rounded result to an unsigned short value 174 * (16Bit). This behavior can be controlled by the second parameter passed to this method. If 175 * set to <code>true</code> a image with 32Bit data depth and INT Databuffer will be created. 176 * Otherwise a 16Bit Image with an USHORT Databuffer will be created. 177 * 178 * @param data 179 * @param use32Bits 180 * @param scale 181 * @param offset 182 * @return result will be a <code>BufferedImage</code> with a GRAY colorspace. 183 */ 184 public static BufferedImage rawData2Image( float[][] data, boolean use32Bits, float scale, float offset ) { 185 BufferedImage img = null; 186 if ( use32Bits ) { 187 img = new BufferedImage( data[0].length, data.length, BufferedImage.TYPE_INT_ARGB ); 188 Raster raster = img.getData(); 189 DataBuffer buffer = raster.getDataBuffer(); 190 for ( int i = 0; i < data.length; i++ ) { 191 for ( int j = 0; j < data[0].length; j++ ) { 192 int pos = data[0].length * i + j; 193 buffer.setElem( pos, Float.floatToIntBits( data[i][j] ) ); 194 } 195 } 196 img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) ); 197 } else { 198 img = createImage( DataBuffer.TYPE_USHORT, data[0].length, data.length ); 199 Raster raster = img.getData(); 200 DataBuffer buffer = raster.getDataBuffer(); 201 for ( int i = 0; i < data.length; i++ ) { 202 for ( int j = 0; j < data[0].length; j++ ) { 203 int pos = data[0].length * i + j; 204 buffer.setElem( pos, Math.round( (data[i][j] + offset) * scale) ); 205 } 206 } 207 img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) ); 208 } 209 210 return img; 211 } 212 213 /** 214 * Special version of the method which creates a new BufferedImage according to the models 215 * given. 216 * 217 * @return result will be a <code>BufferedImage</code> with the given color model 218 * 219 * @param data 220 * data to wrap 221 * @param use32Bits 222 * @param colorModel 223 * @param sampleModel 224 */ 225 public static BufferedImage rawData2Image( float[][] data, boolean use32Bits, ColorModel colorModel, 226 SampleModel sampleModel ) { 227 228 BufferedImage img = null; 229 if ( use32Bits ) { 230 SampleModel sm = sampleModel.createCompatibleSampleModel( data[0].length, data.length ); 231 232 WritableRaster raster = Raster.createWritableRaster( sm, null ); 233 234 img = new BufferedImage( colorModel, raster, true, new Hashtable<Object, Object>() ); 235 236 for ( int i = 0; i < data.length; i++ ) { 237 for ( int j = 0; j < data[i].length; j++ ) { 238 img.setRGB( j, i, Float.floatToRawIntBits( data[i][j] ) ); 239 } 240 } 241 242 } else { 243 img = createImage( DataBuffer.TYPE_USHORT, data[0].length, data.length ); 244 Raster raster = img.getData(); 245 DataBuffer buffer = raster.getDataBuffer(); 246 for ( int i = 0; i < data.length; i++ ) { 247 for ( int j = 0; j < data[i].length; j++ ) { 248 int pos = data[i].length * i + j; 249 buffer.setElem( pos, Math.round( data[i][j] * 10 ) ); 250 } 251 } 252 img.setData( Raster.createRaster( img.getSampleModel(), buffer, null ) ); 253 } 254 255 return img; 256 } 257 }