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