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 }