Mercurial > hg > digilib-old
comparison servlet/src/digilib/image/ImageLoaderDocuImage.java @ 181:afe7ff98bb71
Servlet version 1.18b1
- new transfer mode "rawfile" with mime-type application/octet-stream
- finally proper logging with Log4J!
- therefore a lot of debugging-prints changed
- the Util class is now useless
- ServletOps and FileOps are now purely static
| author | robcast |
|---|---|
| date | Fri, 21 Nov 2003 00:17:31 +0100 |
| parents | d40922628e4a |
| children | 1a65d8e43620 |
comparison
equal
deleted
inserted
replaced
| 180:bd87f802bea1 | 181:afe7ff98bb71 |
|---|---|
| 41 import digilib.io.ImageFile; | 41 import digilib.io.ImageFile; |
| 42 import digilib.io.FileOpException; | 42 import digilib.io.FileOpException; |
| 43 | 43 |
| 44 /** Implementation of DocuImage using the ImageLoader API of Java 1.4 and Java2D. */ | 44 /** Implementation of DocuImage using the ImageLoader API of Java 1.4 and Java2D. */ |
| 45 public class ImageLoaderDocuImage extends DocuImageImpl { | 45 public class ImageLoaderDocuImage extends DocuImageImpl { |
| 46 | 46 |
| 47 /** image object */ | 47 /** image object */ |
| 48 protected BufferedImage img; | 48 protected BufferedImage img; |
| 49 /** interpolation type */ | 49 /** interpolation type */ |
| 50 protected int interpol; | 50 protected int interpol; |
| 51 /** ImageIO image reader */ | 51 /** ImageIO image reader */ |
| 60 | 60 |
| 61 public void setQuality(int qual) { | 61 public void setQuality(int qual) { |
| 62 quality = qual; | 62 quality = qual; |
| 63 // setup interpolation quality | 63 // setup interpolation quality |
| 64 if (qual > 0) { | 64 if (qual > 0) { |
| 65 util.dprintln(4, "quality q1"); | 65 logger.debug("quality q1"); |
| 66 interpol = AffineTransformOp.TYPE_BILINEAR; | 66 interpol = AffineTransformOp.TYPE_BILINEAR; |
| 67 } else { | 67 } else { |
| 68 util.dprintln(4, "quality q0"); | 68 logger.debug("quality q0"); |
| 69 interpol = AffineTransformOp.TYPE_NEAREST_NEIGHBOR; | 69 interpol = AffineTransformOp.TYPE_NEAREST_NEIGHBOR; |
| 70 } | 70 } |
| 71 } | 71 } |
| 72 | 72 |
| 73 public int getHeight() { | 73 public int getHeight() { |
| 77 h = reader.getHeight(0); | 77 h = reader.getHeight(0); |
| 78 } else { | 78 } else { |
| 79 h = img.getHeight(); | 79 h = img.getHeight(); |
| 80 } | 80 } |
| 81 } catch (IOException e) { | 81 } catch (IOException e) { |
| 82 e.printStackTrace(); | 82 logger.debug("error in getHeight", e); |
| 83 } | 83 } |
| 84 return h; | 84 return h; |
| 85 } | 85 } |
| 86 | 86 |
| 87 public int getWidth() { | 87 public int getWidth() { |
| 91 w = reader.getWidth(0); | 91 w = reader.getWidth(0); |
| 92 } else { | 92 } else { |
| 93 w = img.getWidth(); | 93 w = img.getWidth(); |
| 94 } | 94 } |
| 95 } catch (IOException e) { | 95 } catch (IOException e) { |
| 96 e.printStackTrace(); | 96 logger.debug("error in getHeight", e); |
| 97 } | 97 } |
| 98 return w; | 98 return w; |
| 99 } | 99 } |
| 100 | 100 |
| 101 /* load image file */ | 101 /* load image file */ |
| 102 public void loadImage(ImageFile f) throws FileOpException { | 102 public void loadImage(ImageFile f) throws FileOpException { |
| 103 util.dprintln(10, "loadImage!"); | 103 logger.debug("loadImage!"); |
| 104 //System.gc(); | 104 //System.gc(); |
| 105 try { | 105 try { |
| 106 img = ImageIO.read(f.getFile()); | 106 img = ImageIO.read(f.getFile()); |
| 107 if (img == null) { | 107 if (img == null) { |
| 108 util.dprintln(3, "ERROR(loadImage): unable to load file"); | |
| 109 throw new FileOpException("Unable to load File!"); | 108 throw new FileOpException("Unable to load File!"); |
| 110 } | 109 } |
| 111 } catch (IOException e) { | 110 } catch (IOException e) { |
| 112 throw new FileOpException("Error reading image."); | 111 throw new FileOpException("Error reading image."); |
| 113 } | 112 } |
| 127 //String ext = f.getName().substring(f.getName().lastIndexOf('.')+1); | 126 //String ext = f.getName().substring(f.getName().lastIndexOf('.')+1); |
| 128 //Iterator readers = ImageIO.getImageReadersBySuffix(ext); | 127 //Iterator readers = ImageIO.getImageReadersBySuffix(ext); |
| 129 Iterator readers = ImageIO.getImageReadersByMIMEType(f.getMimetype()); | 128 Iterator readers = ImageIO.getImageReadersByMIMEType(f.getMimetype()); |
| 130 reader = (ImageReader) readers.next(); | 129 reader = (ImageReader) readers.next(); |
| 131 /* are there more readers? */ | 130 /* are there more readers? */ |
| 132 System.out.println("this reader: " + reader.getClass()); | 131 logger.debug("this reader: " + reader.getClass()); |
| 133 while (readers.hasNext()) { | 132 while (readers.hasNext()) { |
| 134 System.out.println("next reader: " + readers.next().getClass()); | 133 logger.debug("next reader: " + readers.next().getClass()); |
| 135 } | 134 } |
| 136 //*/ | 135 //*/ |
| 137 reader.setInput(istream); | 136 reader.setInput(istream); |
| 138 if (reader == null) { | 137 if (reader == null) { |
| 139 util.dprintln(3, "ERROR(loadImage): unable to load file"); | |
| 140 throw new FileOpException("Unable to load File!"); | 138 throw new FileOpException("Unable to load File!"); |
| 141 } | 139 } |
| 142 imgFile = f.getFile(); | 140 imgFile = f.getFile(); |
| 143 } | 141 } |
| 144 | 142 |
| 155 readParam.setSourceRegion(region); | 153 readParam.setSourceRegion(region); |
| 156 readParam.setSourceSubsampling(prescale, prescale, 0, 0); | 154 readParam.setSourceSubsampling(prescale, prescale, 0, 0); |
| 157 // read image | 155 // read image |
| 158 img = reader.read(0, readParam); | 156 img = reader.read(0, readParam); |
| 159 } catch (IOException e) { | 157 } catch (IOException e) { |
| 160 util.dprintln(3, "ERROR(loadImage): unable to load file"); | |
| 161 throw new FileOpException("Unable to load File!"); | 158 throw new FileOpException("Unable to load File!"); |
| 162 } | 159 } |
| 163 if (img == null) { | 160 if (img == null) { |
| 164 util.dprintln(3, "ERROR(loadImage): unable to load file"); | |
| 165 throw new FileOpException("Unable to load File!"); | 161 throw new FileOpException("Unable to load File!"); |
| 166 } | 162 } |
| 167 } | 163 } |
| 168 | 164 |
| 169 /* write image of type mt to Stream */ | 165 /* write image of type mt to Stream */ |
| 170 public void writeImage(String mt, OutputStream ostream) | 166 public void writeImage(String mt, OutputStream ostream) |
| 171 throws FileOpException { | 167 throws FileOpException { |
| 172 util.dprintln(10, "writeImage!"); | 168 logger.debug("writeImage!"); |
| 173 try { | 169 try { |
| 174 // setup output | 170 // setup output |
| 175 String type = "png"; | 171 String type = "png"; |
| 176 if (mt == "image/jpeg") { | 172 if (mt == "image/jpeg") { |
| 177 type = "jpeg"; | 173 type = "jpeg"; |
| 178 } else if (mt == "image/png") { | 174 } else if (mt == "image/png") { |
| 179 type = "png"; | 175 type = "png"; |
| 180 } else { | 176 } else { |
| 181 // unknown mime type | 177 // unknown mime type |
| 182 util.dprintln(2, "ERROR(writeImage): Unknown mime type " + mt); | |
| 183 throw new FileOpException("Unknown mime type: " + mt); | 178 throw new FileOpException("Unknown mime type: " + mt); |
| 184 } | 179 } |
| 185 | 180 |
| 186 /* | 181 /* |
| 187 * JPEG doesn't do transparency so we have to convert any RGBA | 182 * JPEG doesn't do transparency so we have to convert any RGBA |
| 188 * image to RGB :-( *Java2D BUG* | 183 * image to RGB :-( *Java2D BUG* |
| 189 */ | 184 */ |
| 190 if ((type == "jpeg") && (img.getColorModel().hasAlpha())) { | 185 if ((type == "jpeg") && (img.getColorModel().hasAlpha())) { |
| 191 util.dprintln(2, "BARF: JPEG with transparency!!"); | 186 logger.debug("BARF: JPEG with transparency!!"); |
| 192 int w = img.getWidth(); | 187 int w = img.getWidth(); |
| 193 int h = img.getHeight(); | 188 int h = img.getHeight(); |
| 194 // BufferedImage.TYPE_INT_RGB seems to be fastest (JDK1.4.1, | 189 // BufferedImage.TYPE_INT_RGB seems to be fastest (JDK1.4.1, |
| 195 // OSX) | 190 // OSX) |
| 196 int destType = BufferedImage.TYPE_INT_RGB; | 191 int destType = BufferedImage.TYPE_INT_RGB; |
| 205 return; | 200 return; |
| 206 } else { | 201 } else { |
| 207 throw new FileOpException("Error writing image: Unknown image format!"); | 202 throw new FileOpException("Error writing image: Unknown image format!"); |
| 208 } | 203 } |
| 209 } catch (IOException e) { | 204 } catch (IOException e) { |
| 210 // e.printStackTrace(); | |
| 211 throw new FileOpException("Error writing image."); | 205 throw new FileOpException("Error writing image."); |
| 212 } | 206 } |
| 213 } | 207 } |
| 214 | 208 |
| 215 public void scale(double scale, double scaleY) throws ImageOpException { | 209 public void scale(double scale, double scaleY) throws ImageOpException { |
| 234 (int) dstBounds.getHeight(), | 228 (int) dstBounds.getHeight(), |
| 235 img.getType()); | 229 img.getType()); |
| 236 } | 230 } |
| 237 scaledImg = scaleOp.filter(img, scaledImg); | 231 scaledImg = scaleOp.filter(img, scaledImg); |
| 238 //DEBUG | 232 //DEBUG |
| 239 util.dprintln( | 233 logger.debug("SCALE: " |
| 240 3, | |
| 241 "SCALE: " | |
| 242 + scale | 234 + scale |
| 243 + " ->" | 235 + " ->" |
| 244 + scaledImg.getWidth() | 236 + scaledImg.getWidth() |
| 245 + "x" | 237 + "x" |
| 246 + scaledImg.getHeight()); | 238 + scaledImg.getHeight()); |
| 247 if (scaledImg == null) { | 239 if (scaledImg == null) { |
| 248 util.dprintln(2, "ERROR(cropAndScale): error in scale"); | |
| 249 throw new ImageOpException("Unable to scale"); | 240 throw new ImageOpException("Unable to scale"); |
| 250 } | 241 } |
| 251 img = scaledImg; | 242 img = scaledImg; |
| 252 } | 243 } |
| 253 | 244 |
| 254 public void blur(int radius) throws ImageOpException { | 245 public void blur(int radius) throws ImageOpException { |
| 255 //DEBUG | 246 //DEBUG |
| 256 util.dprintln(4, "blur: " + radius); | 247 logger.debug("blur: " + radius); |
| 257 // minimum radius is 2 | 248 // minimum radius is 2 |
| 258 int klen = Math.max(radius, 2); | 249 int klen = Math.max(radius, 2); |
| 259 int ksize = klen * klen; | 250 int ksize = klen * klen; |
| 260 // kernel is constant 1/k | 251 // kernel is constant 1/k |
| 261 float f = 1f / ksize; | 252 float f = 1f / ksize; |
| 275 img.getHeight(), | 266 img.getHeight(), |
| 276 img.getType()); | 267 img.getType()); |
| 277 } | 268 } |
| 278 blurredImg = blurOp.filter(img, blurredImg); | 269 blurredImg = blurOp.filter(img, blurredImg); |
| 279 if (blurredImg == null) { | 270 if (blurredImg == null) { |
| 280 util.dprintln(2, "ERROR(cropAndScale): error in scale"); | |
| 281 throw new ImageOpException("Unable to scale"); | 271 throw new ImageOpException("Unable to scale"); |
| 282 } | 272 } |
| 283 img = blurredImg; | 273 img = blurredImg; |
| 284 } | 274 } |
| 285 | 275 |
| 286 public void crop(int x_off, int y_off, int width, int height) | 276 public void crop(int x_off, int y_off, int width, int height) |
| 287 throws ImageOpException { | 277 throws ImageOpException { |
| 288 // setup Crop | 278 // setup Crop |
| 289 BufferedImage croppedImg = img.getSubimage(x_off, y_off, width, height); | 279 BufferedImage croppedImg = img.getSubimage(x_off, y_off, width, height); |
| 290 util.dprintln( | 280 logger.debug("CROP:" + croppedImg.getWidth() + "x" + croppedImg.getHeight()); |
| 291 3, | |
| 292 "CROP:" + croppedImg.getWidth() + "x" + croppedImg.getHeight()); | |
| 293 //DEBUG | 281 //DEBUG |
| 294 // util.dprintln(2, " time | 282 // util.dprintln(2, " time |
| 295 // "+(System.currentTimeMillis()-startTime)+"ms"); | 283 // "+(System.currentTimeMillis()-startTime)+"ms"); |
| 296 if (croppedImg == null) { | 284 if (croppedImg == null) { |
| 297 util.dprintln(2, "ERROR(cropAndScale): error in crop"); | |
| 298 throw new ImageOpException("Unable to crop"); | 285 throw new ImageOpException("Unable to crop"); |
| 299 } | 286 } |
| 300 img = croppedImg; | 287 img = croppedImg; |
| 301 } | 288 } |
| 302 | 289 |
| 328 * We do only 3 (RGB) bands. | 315 * We do only 3 (RGB) bands. |
| 329 */ | 316 */ |
| 330 | 317 |
| 331 int ncol = img.getColorModel().getNumColorComponents(); | 318 int ncol = img.getColorModel().getNumColorComponents(); |
| 332 if ((ncol != 3) || (rgbm.length != 3) || (rgba.length != 3)) { | 319 if ((ncol != 3) || (rgbm.length != 3) || (rgba.length != 3)) { |
| 333 util.dprintln( | 320 logger.debug("ERROR(enhance): unknown number of color bands or coefficients (" |
| 334 2, | |
| 335 "ERROR(enhance): unknown number of color bands or coefficients (" | |
| 336 + ncol | 321 + ncol |
| 337 + ")"); | 322 + ")"); |
| 338 return; | 323 return; |
| 339 } | 324 } |
| 340 RescaleOp scaleOp = | 325 RescaleOp scaleOp = |
| 408 rotOp = new AffineTransformOp(trafo, interpol); | 393 rotOp = new AffineTransformOp(trafo, interpol); |
| 409 BufferedImage rotImg = rotOp.filter(img, null); | 394 BufferedImage rotImg = rotOp.filter(img, null); |
| 410 // calculate new bounding box | 395 // calculate new bounding box |
| 411 //Rectangle2D bounds = rotOp.getBounds2D(img); | 396 //Rectangle2D bounds = rotOp.getBounds2D(img); |
| 412 if (rotImg == null) { | 397 if (rotImg == null) { |
| 413 util.dprintln(2, "ERROR: error in rotate"); | |
| 414 throw new ImageOpException("Unable to rotate"); | 398 throw new ImageOpException("Unable to rotate"); |
| 415 } | 399 } |
| 416 img = rotImg; | 400 img = rotImg; |
| 417 // crop new image (with self-made rounding) | 401 // crop new image (with self-made rounding) |
| 418 /* | 402 /* |
| 448 new AffineTransformOp( | 432 new AffineTransformOp( |
| 449 new AffineTransform(mx, 0, 0, my, tx, ty), | 433 new AffineTransform(mx, 0, 0, my, tx, ty), |
| 450 interpol); | 434 interpol); |
| 451 BufferedImage mirImg = mirOp.filter(img, null); | 435 BufferedImage mirImg = mirOp.filter(img, null); |
| 452 if (mirImg == null) { | 436 if (mirImg == null) { |
| 453 util.dprintln(2, "ERROR: error in mirror"); | |
| 454 throw new ImageOpException("Unable to mirror"); | 437 throw new ImageOpException("Unable to mirror"); |
| 455 } | 438 } |
| 456 img = mirImg; | 439 img = mirImg; |
| 457 } | 440 } |
| 458 | 441 |
| 459 /* (non-Javadoc) @see java.lang.Object#finalize() */ | 442 /* (non-Javadoc) @see java.lang.Object#finalize() */ |
| 460 protected void finalize() throws Throwable { | 443 protected void finalize() throws Throwable { |
| 461 //System.out.println("FIN de ImageLoaderDocuImage!"); | |
| 462 // we must dispose the ImageReader because it keeps the filehandle | 444 // we must dispose the ImageReader because it keeps the filehandle |
| 463 // open! | 445 // open! |
| 464 reader.dispose(); | 446 reader.dispose(); |
| 465 reader = null; | 447 reader = null; |
| 466 img = null; | 448 img = null; |
