Mercurial > hg > digilib-old
annotate servlet/src/digilib/image/ImageLoaderDocuImage.java @ 863:1641fab276ee stream
fixing bugs from cleanup...
author | robcast |
---|---|
date | Wed, 09 Mar 2011 11:03:29 +0100 |
parents | 74062b7d9b22 |
children | 83e747b2a98f |
rev | line source |
---|---|
1 | 1 /* ImageLoaderDocuImage -- Image class implementation using JDK 1.4 ImageLoader |
2 | |
279 | 3 Digital Image Library servlet components |
1 | 4 |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
5 Copyright (C) 2002 - 2011 Robert Casties (robcast@mail.berlios.de) |
1 | 6 |
279 | 7 This program is free software; you can redistribute it and/or modify it |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2 of the License, or (at your | |
10 option) any later version. | |
11 | |
12 Please read license.txt for the full details. A copy of the GPL | |
13 may be found at http://www.gnu.org/copyleft/lgpl.html | |
1 | 14 |
279 | 15 You should have received a copy of the GNU General Public License |
16 along with this program; if not, write to the Free Software | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 */ | |
1 | 19 |
20 package digilib.image; | |
21 | |
496 | 22 import java.awt.Image; |
85 | 23 import java.awt.Rectangle; |
207 | 24 import java.awt.RenderingHints; |
829 | 25 import java.awt.color.ColorSpace; |
73 | 26 import java.awt.geom.AffineTransform; |
101 | 27 import java.awt.geom.Rectangle2D; |
73 | 28 import java.awt.image.AffineTransformOp; |
860 | 29 import java.awt.image.BandCombineOp; |
73 | 30 import java.awt.image.BufferedImage; |
834
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
31 import java.awt.image.ByteLookupTable; |
829 | 32 import java.awt.image.ColorConvertOp; |
838 | 33 import java.awt.image.ColorModel; |
144 | 34 import java.awt.image.ConvolveOp; |
35 import java.awt.image.Kernel; | |
834
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
36 import java.awt.image.LookupOp; |
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
37 import java.awt.image.LookupTable; |
85 | 38 import java.awt.image.RescaleOp; |
863 | 39 import java.awt.image.WritableRaster; |
73 | 40 import java.io.IOException; |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
41 import java.io.OutputStream; |
89 | 42 import java.io.RandomAccessFile; |
464 | 43 import java.util.Arrays; |
85 | 44 import java.util.Iterator; |
1 | 45 |
352 | 46 import javax.imageio.IIOImage; |
73 | 47 import javax.imageio.ImageIO; |
85 | 48 import javax.imageio.ImageReadParam; |
49 import javax.imageio.ImageReader; | |
352 | 50 import javax.imageio.ImageWriteParam; |
51 import javax.imageio.ImageWriter; | |
220 | 52 import javax.imageio.stream.FileImageInputStream; |
85 | 53 import javax.imageio.stream.ImageInputStream; |
352 | 54 import javax.imageio.stream.ImageOutputStream; |
570 | 55 import javax.servlet.ServletException; |
1 | 56 |
207 | 57 import digilib.io.FileOpException; |
464 | 58 import digilib.io.FileOps; |
579
efd7a223f819
try: ImageInput as interface, ImageFile inherits from Dirent and implements ImageInput
robcast
parents:
574
diff
changeset
|
59 import digilib.io.ImageInput; |
596 | 60 import digilib.util.ImageSize; |
1 | 61 |
73 | 62 /** Implementation of DocuImage using the ImageLoader API of Java 1.4 and Java2D. */ |
564 | 63 public class ImageLoaderDocuImage extends ImageInfoDocuImage { |
590 | 64 |
86 | 65 /** image object */ |
66 protected BufferedImage img; | |
570 | 67 |
86 | 68 /** interpolation type */ |
838 | 69 protected RenderingHints renderHint = null; |
279 | 70 |
834
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
71 /** convolution kernels for blur() */ |
590 | 72 protected static Kernel[] convolutionKernels = { |
73 null, | |
74 new Kernel(1, 1, new float[] {1f}), | |
75 new Kernel(2, 2, new float[] {0.25f, 0.25f, 0.25f, 0.25f}), | |
76 new Kernel(3, 3, new float[] {1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f}) | |
77 }; | |
279 | 78 |
854 | 79 /* lookup tables for inverting images (byte) */ |
841
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
80 protected static LookupTable invertSingleByteTable; |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
81 protected static LookupTable invertRgbaByteTable; |
854 | 82 protected static boolean needsInvertRgba = false; |
860 | 83 /* RescaleOp for contrast/brightness operation */ |
854 | 84 protected static boolean needsRescaleRgba = false; |
860 | 85 /* lookup tables for false-color */ |
86 protected static LookupTable mapBgrByteTable; | |
854 | 87 |
834
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
88 static { |
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
89 byte[] invertByte = new byte[256]; |
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
90 byte[] orderedByte = new byte[256]; |
841
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
91 byte[] nullByte = new byte[256]; |
860 | 92 byte[] mapR = new byte[256]; |
93 byte[] mapG = new byte[256]; | |
94 byte[] mapB = new byte[256]; | |
834
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
95 for (int i = 0; i < 256; ++i) { |
860 | 96 // counting down |
834
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
97 invertByte[i] = (byte) (256 - i); |
860 | 98 // counting up |
834
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
99 orderedByte[i] = (byte) i; |
860 | 100 // constant 0 |
841
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
101 nullByte[i] = 0; |
860 | 102 // three overlapping slopes |
103 if (i < 64) { | |
104 mapR[i] = 0; | |
105 mapG[i] = (byte) (4 * i); | |
106 mapB[i] = (byte) 255; | |
107 } else if (i >= 64 && i < 192) { | |
108 mapR[i] = (byte) (2 * (i - 64)); | |
109 mapG[i] = (byte) 255; | |
110 mapB[i] = (byte) (255 - 2 * (i - 64)); | |
111 } else { | |
112 mapR[i] = (byte) 255; | |
861 | 113 mapG[i] = (byte) (255 - (4 * (i - 192))); |
860 | 114 mapB[i] = 0; |
115 } | |
834
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
116 } |
841
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
117 // should(!) work for all color models |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
118 invertSingleByteTable = new ByteLookupTable(0, invertByte); |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
119 // but doesn't work with alpha channel on all platforms |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
120 String ver = System.getProperty("java.version"); |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
121 String os = System.getProperty("os.name"); |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
122 logger.debug("os="+os+" ver="+ver); |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
123 if (os.startsWith("Linux") && ver.startsWith("1.6")) { |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
124 // GRAB(WTF?) works in Linux JDK1.6 with transparency |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
125 invertRgbaByteTable = new ByteLookupTable(0, new byte[][] { |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
126 invertByte, invertByte, orderedByte, invertByte}); |
854 | 127 needsInvertRgba = true; |
128 needsRescaleRgba = true; | |
841
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
129 } else { |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
130 invertRgbaByteTable = invertSingleByteTable; |
3519cfa11a0b
organised special juju for invert on linux jdk 1.6.
robcast
parents:
839
diff
changeset
|
131 } |
860 | 132 // this hopefully works for all |
133 mapBgrByteTable = new ByteLookupTable(0, new byte[][] { | |
134 mapR, mapG, mapB}); | |
834
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
135 } |
c07c21ac78f9
color invert operation. doesn't work with all image types yet...
robcast
parents:
831
diff
changeset
|
136 |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
137 /** the size of the current image */ |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
138 protected ImageSize imageSize; |
590 | 139 |
140 | |
85 | 141 /* loadSubimage is supported. */ |
142 public boolean isSubimageSupported() { | |
143 return true; | |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
144 } |
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
145 |
85 | 146 public void setQuality(int qual) { |
147 quality = qual; | |
207 | 148 renderHint = new RenderingHints(null); |
352 | 149 // hint.put(RenderingHints.KEY_ANTIALIASING, |
279 | 150 // RenderingHints.VALUE_ANTIALIAS_OFF); |
85 | 151 // setup interpolation quality |
152 if (qual > 0) { | |
181 | 153 logger.debug("quality q1"); |
279 | 154 renderHint.put(RenderingHints.KEY_INTERPOLATION, |
155 RenderingHints.VALUE_INTERPOLATION_BICUBIC); | |
85 | 156 } else { |
181 | 157 logger.debug("quality q0"); |
279 | 158 renderHint.put(RenderingHints.KEY_INTERPOLATION, |
159 RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); | |
85 | 160 } |
161 } | |
86 | 162 |
570 | 163 /* returns the size of the current image */ |
164 public ImageSize getSize() { | |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
165 if (imageSize == null) { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
166 int h = 0; |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
167 int w = 0; |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
168 try { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
169 if (img == null) { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
170 ImageReader reader = getReader(input); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
171 // get size from ImageReader |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
172 h = reader.getHeight(0); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
173 w = reader.getWidth(0); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
174 } else { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
175 // get size from image |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
176 h = img.getHeight(); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
177 w = img.getWidth(); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
178 } |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
179 imageSize = new ImageSize(w, h); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
180 } catch (IOException e) { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
181 logger.debug("error in getSize:", e); |
570 | 182 } |
183 } | |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
184 return imageSize; |
570 | 185 } |
1 | 186 |
464 | 187 /* returns a list of supported image formats */ |
531 | 188 public Iterator<String> getSupportedFormats() { |
464 | 189 String[] formats = ImageIO.getReaderFormatNames(); |
190 return Arrays.asList(formats).iterator(); | |
191 } | |
192 | |
588 | 193 /* Check image size and type and store in ImageInput */ |
194 public ImageInput identify(ImageInput input) throws IOException { | |
462
03ff7238c9d4
second try for flashpix support (doesn't work currently...)
robcast
parents:
402
diff
changeset
|
195 // try parent method first |
588 | 196 ImageInput ii = super.identify(input); |
197 if (ii != null) { | |
198 return ii; | |
462
03ff7238c9d4
second try for flashpix support (doesn't work currently...)
robcast
parents:
402
diff
changeset
|
199 } |
588 | 200 logger.debug("identifying (ImageIO) " + input); |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
201 ImageReader reader = null; |
590 | 202 try { |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
203 /* |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
204 * try ImageReader |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
205 */ |
590 | 206 reader = getReader(input); |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
207 // set size |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
208 ImageSize d = new ImageSize(reader.getWidth(0), reader.getHeight(0)); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
209 input.setSize(d); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
210 // set mime type |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
211 if (input.getMimetype() == null) { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
212 if (input.hasFile()) { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
213 String t = FileOps.mimeForFile(input.getFile()); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
214 input.setMimetype(t); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
215 } else { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
216 // FIXME: is format name a mime type??? |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
217 String t = reader.getFormatName(); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
218 input.setMimetype(t); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
219 } |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
220 } |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
221 return input; |
590 | 222 } catch (FileOpException e) { |
223 // maybe just our class doesn't know what to do | |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
224 logger.error("ImageLoaderDocuimage unable to identify:", e); |
590 | 225 return null; |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
226 } finally { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
227 if (reader != null) { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
228 reader.dispose(); |
588 | 229 } |
462
03ff7238c9d4
second try for flashpix support (doesn't work currently...)
robcast
parents:
402
diff
changeset
|
230 } |
03ff7238c9d4
second try for flashpix support (doesn't work currently...)
robcast
parents:
402
diff
changeset
|
231 } |
03ff7238c9d4
second try for flashpix support (doesn't work currently...)
robcast
parents:
402
diff
changeset
|
232 |
03ff7238c9d4
second try for flashpix support (doesn't work currently...)
robcast
parents:
402
diff
changeset
|
233 /* load image file */ |
588 | 234 public void loadImage(ImageInput ii) throws FileOpException { |
235 logger.debug("loadImage: " + ii); | |
236 this.input = ii; | |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
237 try { |
588 | 238 if (ii.hasImageInputStream()) { |
239 img = ImageIO.read(ii.getImageInputStream()); | |
240 } else if (ii.hasFile()) { | |
241 img = ImageIO.read(ii.getFile()); | |
242 } | |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
243 } catch (IOException e) { |
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
244 throw new FileOpException("Error reading image."); |
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
245 } |
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
246 } |
1 | 247 |
279 | 248 /** |
249 * Get an ImageReader for the image file. | |
250 * | |
251 * @return | |
252 */ | |
587 | 253 public ImageReader getReader(ImageInput input) throws IOException { |
254 logger.debug("get ImageReader for " + input); | |
255 ImageInputStream istream = null; | |
256 if (input.hasImageInputStream()) { | |
257 // stream input | |
258 istream = input.getImageInputStream(); | |
259 } else if (input.hasFile()) { | |
260 // file only input | |
261 RandomAccessFile rf = new RandomAccessFile(input.getFile(), "r"); | |
262 istream = new FileImageInputStream(rf); | |
263 } else { | |
264 throw new FileOpException("Unable to get data from ImageInput"); | |
148 | 265 } |
565 | 266 Iterator<ImageReader> readers; |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
267 String mt = null; |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
268 if (input.hasMimetype()) { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
269 // check hasMimetype first or we might get into a loop |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
270 mt = input.getMimetype(); |
821 | 271 } else { |
272 // try file extension | |
273 mt = FileOps.mimeForFile(input.getFile()); | |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
274 } |
565 | 275 if (mt == null) { |
276 logger.debug("No mime-type. Trying automagic."); | |
277 readers = ImageIO.getImageReaders(istream); | |
278 } else { | |
279 logger.debug("File type:" + mt); | |
280 readers = ImageIO.getImageReadersByMIMEType(mt); | |
281 } | |
279 | 282 if (!readers.hasNext()) { |
565 | 283 throw new FileOpException("Can't find Reader to load File!"); |
279 | 284 } |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
285 ImageReader reader = readers.next(); |
149 | 286 /* are there more readers? */ |
207 | 287 logger.debug("ImageIO: this reader: " + reader.getClass()); |
564 | 288 /* while (readers.hasNext()) { |
207 | 289 logger.debug("ImageIO: next reader: " + readers.next().getClass()); |
564 | 290 } */ |
89 | 291 reader.setInput(istream); |
279 | 292 return reader; |
85 | 293 } |
294 | |
295 /* Load an image file into the Object. */ | |
588 | 296 public void loadSubimage(ImageInput ii, Rectangle region, int prescale) |
279 | 297 throws FileOpException { |
207 | 298 logger.debug("loadSubimage"); |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
299 this.input = ii; |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
300 ImageReader reader = null; |
85 | 301 try { |
590 | 302 reader = getReader(ii); |
85 | 303 // set up reader parameters |
304 ImageReadParam readParam = reader.getDefaultReadParam(); | |
305 readParam.setSourceRegion(region); | |
220 | 306 if (prescale > 1) { |
307 readParam.setSourceSubsampling(prescale, prescale, 0, 0); | |
308 } | |
85 | 309 // read image |
207 | 310 logger.debug("loading.."); |
85 | 311 img = reader.read(0, readParam); |
207 | 312 logger.debug("loaded"); |
85 | 313 } catch (IOException e) { |
314 throw new FileOpException("Unable to load File!"); | |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
315 } finally { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
316 if (reader != null) { |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
317 reader.dispose(); |
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
318 } |
85 | 319 } |
320 } | |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
321 |
86 | 322 /* write image of type mt to Stream */ |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
323 public void writeImage(String mt, OutputStream ostream) |
570 | 324 throws ImageOpException, ServletException { |
207 | 325 logger.debug("writeImage"); |
353 | 326 // setup output |
327 ImageWriter writer = null; | |
328 ImageOutputStream imgout = null; | |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
329 try { |
353 | 330 imgout = ImageIO.createImageOutputStream(ostream); |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
331 if (mt == "image/jpeg") { |
352 | 332 /* |
333 * JPEG doesn't do transparency so we have to convert any RGBA | |
334 * image to RGB :-( *Java2D BUG* | |
335 */ | |
336 if (img.getColorModel().hasAlpha()) { | |
337 logger.debug("BARF: JPEG with transparency!!"); | |
338 int w = img.getWidth(); | |
339 int h = img.getHeight(); | |
340 // BufferedImage.TYPE_INT_RGB seems to be fastest (JDK1.4.1, | |
341 // OSX) | |
342 int destType = BufferedImage.TYPE_INT_RGB; | |
343 BufferedImage img2 = new BufferedImage(w, h, destType); | |
344 img2.createGraphics().drawImage(img, null, 0, 0); | |
345 img = img2; | |
346 } | |
347 writer = (ImageWriter) ImageIO.getImageWritersByFormatName( | |
348 "jpeg").next(); | |
349 if (writer == null) { | |
570 | 350 throw new ImageOpException("Unable to get JPEG writer"); |
352 | 351 } |
352 ImageWriteParam param = writer.getDefaultWriteParam(); | |
353 if (quality > 1) { | |
354 // change JPEG compression quality | |
353 | 355 param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); |
469
11e11fe4d680
Improved performance of JAIDocuImage for large images
robcast
parents:
464
diff
changeset
|
356 //logger.debug("JPEG qual before: " |
11e11fe4d680
Improved performance of JAIDocuImage for large images
robcast
parents:
464
diff
changeset
|
357 // + Float.toString(param.getCompressionQuality())); |
352 | 358 param.setCompressionQuality(0.9f); |
469
11e11fe4d680
Improved performance of JAIDocuImage for large images
robcast
parents:
464
diff
changeset
|
359 //logger.debug("JPEG qual now: " |
11e11fe4d680
Improved performance of JAIDocuImage for large images
robcast
parents:
464
diff
changeset
|
360 // + Float.toString(param.getCompressionQuality())); |
352 | 361 } |
362 writer.setOutput(imgout); | |
363 // render output | |
364 logger.debug("writing"); | |
365 writer.write(null, new IIOImage(img, null, null), param); | |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
366 } else if (mt == "image/png") { |
352 | 367 // render output |
368 writer = (ImageWriter) ImageIO.getImageWritersByFormatName( | |
369 "png").next(); | |
370 if (writer == null) { | |
570 | 371 throw new ImageOpException("Unable to get PNG writer"); |
352 | 372 } |
373 writer.setOutput(imgout); | |
374 logger.debug("writing"); | |
375 writer.write(img); | |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
376 } else { |
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
377 // unknown mime type |
570 | 378 throw new ImageOpException("Unknown mime type: " + mt); |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
379 } |
140 | 380 |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
381 } catch (IOException e) { |
570 | 382 logger.error("Error writing image:", e); |
383 throw new ServletException("Error writing image:", e); | |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
384 } |
801
72662bb585ba
remove all ServletOutputStream.flush(). (stupid me ;-)
robcast
parents:
596
diff
changeset
|
385 // TODO: should we: finally { writer.dispose(); } |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
386 } |
1 | 387 |
149 | 388 public void scale(double scale, double scaleY) throws ImageOpException { |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
389 logger.debug("scale: " + scale); |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
390 /* for downscaling in high quality the image is blurred first */ |
144 | 391 if ((scale <= 0.5) && (quality > 1)) { |
392 int bl = (int) Math.floor(1 / scale); | |
393 blur(bl); | |
394 } | |
207 | 395 /* then scaled */ |
279 | 396 AffineTransformOp scaleOp = new AffineTransformOp(AffineTransform |
397 .getScaleInstance(scale, scale), renderHint); | |
207 | 398 logger.debug("scaling..."); |
857 | 399 img = scaleOp.filter(img, null); |
400 logger.debug("SCALE: " + scale + " ->" + img.getWidth() + "x" | |
863 | 401 + img.getHeight() + " type=" + img); |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
402 } |
1 | 403 |
144 | 404 public void blur(int radius) throws ImageOpException { |
181 | 405 logger.debug("blur: " + radius); |
144 | 406 // minimum radius is 2 |
407 int klen = Math.max(radius, 2); | |
590 | 408 Kernel blur = null; |
409 if (klen < convolutionKernels.length) { | |
863 | 410 // use precalculated Kernel |
590 | 411 blur = convolutionKernels[klen]; |
412 } else { | |
413 // calculate our own kernel | |
414 int ksize = klen * klen; | |
415 // kernel is constant 1/k | |
416 float f = 1f / ksize; | |
417 float[] kern = new float[ksize]; | |
418 for (int i = 0; i < ksize; ++i) { | |
419 kern[i] = f; | |
420 } | |
421 blur = new Kernel(klen, klen, kern); | |
144 | 422 } |
423 // blur with convolve operation | |
279 | 424 ConvolveOp blurOp = new ConvolveOp(blur, ConvolveOp.EDGE_NO_OP, |
425 renderHint); | |
863 | 426 /* blur needs explicit destination image type for color *Java2D BUG* */ |
427 BufferedImage dest = null; | |
145 | 428 if (img.getType() == BufferedImage.TYPE_3BYTE_BGR) { |
863 | 429 logger.debug("blur: fixing destination image type for "+img); |
430 dest = new BufferedImage(img.getWidth(), img.getHeight(), img | |
279 | 431 .getType()); |
863 | 432 } |
433 img = blurOp.filter(img, dest); | |
434 logger.debug("blurred: "+img); | |
144 | 435 } |
436 | |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
437 public void crop(int x_off, int y_off, int width, int height) |
279 | 438 throws ImageOpException { |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
439 // setup Crop |
857 | 440 img = img.getSubimage(x_off, y_off, width, height); |
441 logger.debug("CROP:" + img.getWidth() + "x" | |
442 + img.getHeight()); | |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
443 } |
1 | 444 |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
445 public void enhance(float mult, float add) throws ImageOpException { |
843
7718c6e832b0
enhance (cont, brgt) operation now with just one float.
robcast
parents:
841
diff
changeset
|
446 RescaleOp op = null; |
854 | 447 logger.debug("enhance: cm=" + img.getColorModel()); |
448 if (needsRescaleRgba) { | |
857 | 449 /* |
450 * Only one constant should work regardless of the number of bands | |
451 * according to the JDK spec. Doesn't work on JDK 1.4 for OSX and | |
452 * Linux (at least). | |
453 * | |
854 | 454 * The number of constants must match the number of bands in the |
455 * image. | |
456 */ | |
457 int ncol = img.getColorModel().getNumComponents(); | |
458 float[] dm = new float[ncol]; | |
459 float[] da = new float[ncol]; | |
460 for (int i = 0; i < ncol; i++) { | |
461 dm[i] = (float) mult; | |
462 da[i] = (float) add; | |
463 } | |
464 op = new RescaleOp(dm, da, null); | |
465 } else { | |
466 op = new RescaleOp(mult, add, renderHint); | |
85 | 467 } |
843
7718c6e832b0
enhance (cont, brgt) operation now with just one float.
robcast
parents:
841
diff
changeset
|
468 op.filter(img, img); |
85 | 469 } |
470 | |
279 | 471 public void enhanceRGB(float[] rgbm, float[] rgba) throws ImageOpException { |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
472 /* |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
473 * The number of constants must match the number of bands in the image. |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
474 * We do only 3 (RGB) bands. |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
475 */ |
86 | 476 int ncol = img.getColorModel().getNumColorComponents(); |
477 if ((ncol != 3) || (rgbm.length != 3) || (rgba.length != 3)) { | |
863 | 478 logger.error("enhanceRGB: unknown number of color bands or coefficients (" |
279 | 479 + ncol + ")"); |
86 | 480 return; |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
481 } |
279 | 482 RescaleOp scaleOp = new RescaleOp(rgbOrdered(rgbm), rgbOrdered(rgba), |
483 null); | |
86 | 484 scaleOp.filter(img, img); |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
485 } |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
486 |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
487 /** |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
488 * Ensures that the array f is in the right order to map the images RGB |
590 | 489 * components. (not sure what happens otherwise) |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
490 */ |
86 | 491 public float[] rgbOrdered(float[] fa) { |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
492 /* |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
493 * TODO: this is UGLY, UGLY!! |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
494 */ |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
495 float[] fb; |
86 | 496 int t = img.getType(); |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
497 if (img.getColorModel().hasAlpha()) { |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
498 fb = new float[4]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
499 if ((t == BufferedImage.TYPE_INT_ARGB) |
279 | 500 || (t == BufferedImage.TYPE_INT_ARGB_PRE)) { |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
501 // RGB Type |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
502 fb[0] = fa[0]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
503 fb[1] = fa[1]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
504 fb[2] = fa[2]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
505 fb[3] = 1f; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
506 } else { |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
507 // this isn't tested :-( |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
508 fb[0] = 1f; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
509 fb[1] = fa[0]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
510 fb[2] = fa[1]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
511 fb[3] = fa[2]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
512 } |
86 | 513 } else { |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
514 fb = new float[3]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
515 if (t == BufferedImage.TYPE_3BYTE_BGR) { |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
516 // BGR Type (actually it looks like RBG...) |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
517 fb[0] = fa[0]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
518 fb[1] = fa[2]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
519 fb[2] = fa[1]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
520 } else { |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
521 fb[0] = fa[0]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
522 fb[1] = fa[1]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
523 fb[2] = fa[2]; |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
524 } |
86 | 525 } |
526 return fb; | |
85 | 527 } |
528 | |
860 | 529 /* |
530 * (non-Javadoc) | |
531 * | |
532 * @see | |
533 * digilib.image.DocuImageImpl#colorOp(digilib.image.DocuImage.ColorOps) | |
534 */ | |
535 public void colorOp(ColorOp colop) throws ImageOpException { | |
536 if (colop == ColorOp.GRAYSCALE) { | |
537 /* | |
538 * convert image to grayscale | |
539 */ | |
540 logger.debug("Color op: grayscaling"); | |
541 ColorModel cm = img.getColorModel(); | |
542 if (cm.getNumColorComponents() == 1) { | |
543 // grayscale already | |
544 return; | |
545 } | |
546 ColorConvertOp op = new ColorConvertOp( | |
547 ColorSpace.getInstance(ColorSpace.CS_GRAY), renderHint); | |
548 // let filter create new image | |
549 img = op.filter(img, null); | |
550 } else if (colop == ColorOp.NTSC_GRAY) { | |
551 /* | |
552 * convert image to grayscale NTSC-style: luminance = 0.2989*red + | |
553 * 0.5870*green + 0.1140*blue | |
554 */ | |
555 logger.debug("Color op: NTSC gray"); | |
556 ColorModel cm = img.getColorModel(); | |
557 if (cm.getNumColorComponents() == 1) { | |
558 // grayscale already | |
559 return; | |
560 } | |
561 float[][] combineFn = new float[1][4]; | |
562 combineFn[0] = rgbOrdered(new float[] { 0.299f, 0.114f, 0.587f, 0f }); | |
563 BandCombineOp op = new BandCombineOp(combineFn, renderHint); | |
863 | 564 // BandCombineOp only works on Rasters so we create a |
860 | 565 // new image and use its Raster |
566 BufferedImage dest = new BufferedImage(img.getWidth(), | |
567 img.getHeight(), BufferedImage.TYPE_BYTE_GRAY); | |
568 op.filter(img.getRaster(), dest.getRaster()); | |
569 img = dest; | |
570 } else if (colop == ColorOp.INVERT) { | |
571 /* | |
572 * invert colors i.e. invert every channel | |
573 */ | |
574 logger.debug("Color op: inverting"); | |
575 LookupTable invtbl = null; | |
576 ColorModel cm = img.getColorModel(); | |
577 if (needsInvertRgba && cm.hasAlpha()) { | |
578 /* | |
579 * should work with one array for all channels, but JDK 1.6 in | |
580 * Linux (at least) is broken :-( | |
581 */ | |
582 invtbl = invertRgbaByteTable; | |
583 } else { | |
584 invtbl = invertSingleByteTable; | |
585 } | |
586 LookupOp op = new LookupOp(invtbl, renderHint); | |
587 logger.debug("colop: image=" + img + " colormodel=" + cm); | |
588 op.filter(img, img); | |
589 } else if (colop == ColorOp.MAP_GRAY_BGR) { | |
590 /* | |
591 * false color image from grayscale (0: blue, 128: green, 255: red) | |
592 */ | |
593 logger.debug("Color op: map_gray_bgr"); | |
594 // convert to grayscale | |
595 ColorConvertOp grayOp = new ColorConvertOp( | |
596 ColorSpace.getInstance(ColorSpace.CS_GRAY), renderHint); | |
597 // create new 3-byte image | |
598 BufferedImage dest = new BufferedImage(img.getWidth(), | |
599 img.getHeight(), BufferedImage.TYPE_3BYTE_BGR); | |
600 img = grayOp.filter(img, dest); | |
601 logger.debug("map_gray: image=" + img); | |
602 // convert to false color | |
603 LookupOp mapOp = new LookupOp(mapBgrByteTable, renderHint); | |
604 mapOp.filter(img, img); | |
605 logger.debug("mapped image=" + img); | |
606 } | |
607 } | |
829 | 608 |
140 | 609 public void rotate(double angle) throws ImageOpException { |
89 | 610 // setup rotation |
611 double rangle = Math.toRadians(angle); | |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
612 // create offset to make shure the rotated image has no negative |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
613 // coordinates |
101 | 614 double w = img.getWidth(); |
615 double h = img.getHeight(); | |
103 | 616 AffineTransform trafo = new AffineTransform(); |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
617 // center of rotation |
103 | 618 double x = (w / 2); |
619 double y = (h / 2); | |
101 | 620 trafo.rotate(rangle, x, y); |
103 | 621 // try rotation to see how far we're out of bounds |
207 | 622 AffineTransformOp rotOp = new AffineTransformOp(trafo, renderHint); |
103 | 623 Rectangle2D rotbounds = rotOp.getBounds2D(img); |
624 double xoff = rotbounds.getX(); | |
625 double yoff = rotbounds.getY(); | |
626 // move image back in line | |
565 | 627 trafo.preConcatenate(AffineTransform.getTranslateInstance(-xoff, -yoff)); |
101 | 628 // transform image |
207 | 629 rotOp = new AffineTransformOp(trafo, renderHint); |
863 | 630 img = rotOp.filter(img, null); |
101 | 631 // calculate new bounding box |
352 | 632 // Rectangle2D bounds = rotOp.getBounds2D(img); |
101 | 633 // crop new image (with self-made rounding) |
170
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
634 /* |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
635 * img = rotImg.getSubimage( (int) (bounds.getX()+0.5), (int) |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
636 * (bounds.getY()+0.5), (int) (bounds.getWidth()+0.5), (int) |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
637 * (bounds.getHeight()+0.5)); |
d40922628e4a
Servlet Version 1.16b2 with new DigilibParameter code.
robcast
parents:
159
diff
changeset
|
638 */ |
86 | 639 } |
85 | 640 |
89 | 641 public void mirror(double angle) throws ImageOpException { |
642 // setup mirror | |
643 double mx = 1; | |
644 double my = 1; | |
645 double tx = 0; | |
646 double ty = 0; | |
144 | 647 if (Math.abs(angle - 0) < epsilon) { // 0 degree |
89 | 648 mx = -1; |
649 tx = getWidth(); | |
144 | 650 } else if (Math.abs(angle - 90) < epsilon) { // 90 degree |
89 | 651 my = -1; |
652 ty = getHeight(); | |
144 | 653 } else if (Math.abs(angle - 180) < epsilon) { // 180 degree |
89 | 654 mx = -1; |
655 tx = getWidth(); | |
144 | 656 } else if (Math.abs(angle - 270) < epsilon) { // 270 degree |
89 | 657 my = -1; |
658 ty = getHeight(); | |
144 | 659 } else if (Math.abs(angle - 360) < epsilon) { // 360 degree |
89 | 660 mx = -1; |
661 tx = getWidth(); | |
662 } | |
279 | 663 AffineTransformOp mirOp = new AffineTransformOp(new AffineTransform(mx, |
664 0, 0, my, tx, ty), renderHint); | |
863 | 665 img = mirOp.filter(img, null); |
79
63c8186455c1
Servlet version 1.6b. Further cleanup and new functionality:
robcast
parents:
73
diff
changeset
|
666 } |
86 | 667 |
207 | 668 public void dispose() { |
819
a23c4c15a6a8
clean up possible resource leaks. better behaviour with unknown image types.
robcast
parents:
801
diff
changeset
|
669 // is this necessary? |
148 | 670 img = null; |
671 } | |
672 | |
533 | 673 public Image getAwtImage(){ |
496 | 674 return (Image) img; |
675 } | |
676 | |
677 | |
1 | 678 } |