001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/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 08:39:07 -0800 (Thu, 27 Dec 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,
076: int height) {
077:
078: ColorModel ccm = new ComponentColorModel(ColorSpace
079: .getInstance(ColorSpace.CS_GRAY), null, false, false,
080: BufferedImage.OPAQUE, type);
081:
082: WritableRaster wr = ccm.createCompatibleWritableRaster(width,
083: height);
084:
085: return new BufferedImage(ccm, wr, false,
086: new Hashtable<Object, Object>());
087:
088: }
089:
090: /**
091: * @return result will be a <code>BufferedImage</code> with a GRAY colorspace and
092: * <code>DataBuffer.TYPE_BYTE</code>
093: *
094: * @param data
095: * data to wrap
096: */
097: public static BufferedImage rawData2Image(byte[][] data) {
098:
099: BufferedImage img = createImage(DataBuffer.TYPE_BYTE,
100: data[0].length, data.length);
101: Raster raster = img.getData();
102: DataBuffer buffer = raster.getDataBuffer();
103:
104: for (int i = 0; i < data.length; i++) {
105: for (int j = 0; j < data[0].length; j++) {
106: int pos = data[0].length * i + j;
107: buffer.setElem(pos, data[i][j]);
108: }
109: }
110: img.setData(Raster.createRaster(img.getSampleModel(), buffer,
111: null));
112: return img;
113: }
114:
115: /**
116: * @return result will be a <code>BufferedImage</code> with a GRAY colorspace and
117: * <code>DataBuffer.TYPE_USHORT</code>
118: *
119: * @param data
120: * data to wrap
121: */
122: public static BufferedImage rawData2Image(short[][] data) {
123: BufferedImage img = createImage(DataBuffer.TYPE_USHORT,
124: data[0].length, data.length);
125: Raster raster = img.getData();
126: DataBuffer buffer = raster.getDataBuffer();
127:
128: for (int i = 0; i < data.length; i++) {
129: for (int j = 0; j < data[0].length; j++) {
130: int pos = data[0].length * i + j;
131: buffer.setElem(pos, data[i][j]);
132: }
133: }
134: img.setData(Raster.createRaster(img.getSampleModel(), buffer,
135: null));
136: return img;
137: }
138:
139: /**
140: * @return result will be a <code>BufferedImage</code> with a GRAY colorspace and
141: * <code>DataBuffer.TYPE_INT</code>
142: *
143: * @param data
144: * data to wrap
145: */
146: public static BufferedImage rawData2Image(int[][] data) {
147: BufferedImage img = createImage(DataBuffer.TYPE_INT,
148: data[0].length, data.length);
149: Raster raster = img.getData();
150: DataBuffer buffer = raster.getDataBuffer();
151:
152: for (int i = 0; i < data.length; i++) {
153: for (int j = 0; j < data[0].length; j++) {
154: int pos = data[0].length * i + j;
155: buffer.setElem(pos, data[i][j]);
156: }
157: }
158: img.setData(Raster.createRaster(img.getSampleModel(), buffer,
159: null));
160: return img;
161: }
162:
163: /**
164: * Float data requires 4 Byte (32Bit) per data cell. It is common to reduce data depth by
165: * multiplying float values with 10 and map the rounded result to an unsigned short value
166: * (16Bit). This behavior can be controlled by the second parameter passed to this method. If
167: * set to <code>true</code> a image with 32Bit data depth and INT Databuffer will be created.
168: * Otherwise a 16Bit Image with an USHORT Databuffer will be created.<br>
169: * A default scale of 10 and no offset will be used
170: *
171: * @return result will be a <code>BufferedImage</code> with a GRAY colorspace.
172: *
173: * @param data
174: * data to wrap
175: * @param use32Bits
176: */
177: public static BufferedImage rawData2Image(float[][] data,
178: boolean use32Bits) {
179: return rawData2Image(data, use32Bits, 10, 0);
180: }
181:
182: /**
183: * Float data requires 4 Byte (32Bit) per data cell. It is common to reduce data depth by
184: * multiplying float values with 10 and map the rounded result to an unsigned short value
185: * (16Bit). This behavior can be controlled by the second parameter passed to this method. If
186: * set to <code>true</code> a image with 32Bit data depth and INT Databuffer will be created.
187: * Otherwise a 16Bit Image with an USHORT Databuffer will be created.
188: *
189: * @param data
190: * @param use32Bits
191: * @param scale
192: * @param offset
193: * @return result will be a <code>BufferedImage</code> with a GRAY colorspace.
194: */
195: public static BufferedImage rawData2Image(float[][] data,
196: boolean use32Bits, float scale, float offset) {
197: BufferedImage img = null;
198: if (use32Bits) {
199: img = new BufferedImage(data[0].length, data.length,
200: BufferedImage.TYPE_INT_ARGB);
201: Raster raster = img.getData();
202: DataBuffer buffer = raster.getDataBuffer();
203: for (int i = 0; i < data.length; i++) {
204: for (int j = 0; j < data[0].length; j++) {
205: int pos = data[0].length * i + j;
206: buffer.setElem(pos, Float
207: .floatToIntBits(data[i][j]));
208: }
209: }
210: img.setData(Raster.createRaster(img.getSampleModel(),
211: buffer, null));
212: } else {
213: img = createImage(DataBuffer.TYPE_USHORT, data[0].length,
214: data.length);
215: Raster raster = img.getData();
216: DataBuffer buffer = raster.getDataBuffer();
217: for (int i = 0; i < data.length; i++) {
218: for (int j = 0; j < data[0].length; j++) {
219: int pos = data[0].length * i + j;
220: buffer.setElem(pos, Math
221: .round((data[i][j] + offset) * scale));
222: }
223: }
224: img.setData(Raster.createRaster(img.getSampleModel(),
225: buffer, null));
226: }
227:
228: return img;
229: }
230:
231: /**
232: * Special version of the method which creates a new BufferedImage according to the models
233: * given.
234: *
235: * @return result will be a <code>BufferedImage</code> with the given color model
236: *
237: * @param data
238: * data to wrap
239: * @param use32Bits
240: * @param colorModel
241: * @param sampleModel
242: */
243: public static BufferedImage rawData2Image(float[][] data,
244: boolean use32Bits, ColorModel colorModel,
245: SampleModel sampleModel) {
246:
247: BufferedImage img = null;
248: if (use32Bits) {
249: SampleModel sm = sampleModel.createCompatibleSampleModel(
250: data[0].length, data.length);
251:
252: WritableRaster raster = Raster.createWritableRaster(sm,
253: null);
254:
255: img = new BufferedImage(colorModel, raster, true,
256: new Hashtable<Object, Object>());
257:
258: for (int i = 0; i < data.length; i++) {
259: for (int j = 0; j < data[i].length; j++) {
260: img.setRGB(j, i, Float
261: .floatToRawIntBits(data[i][j]));
262: }
263: }
264:
265: } else {
266: img = createImage(DataBuffer.TYPE_USHORT, data[0].length,
267: data.length);
268: Raster raster = img.getData();
269: DataBuffer buffer = raster.getDataBuffer();
270: for (int i = 0; i < data.length; i++) {
271: for (int j = 0; j < data[i].length; j++) {
272: int pos = data[i].length * i + j;
273: buffer.setElem(pos, Math.round(data[i][j] * 10));
274: }
275: }
276: img.setData(Raster.createRaster(img.getSampleModel(),
277: buffer, null));
278: }
279:
280: return img;
281: }
282: }
|