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 }