Mercurial > hg > digilib-old
comparison servlet/src/digilib/servlet/Scaler.java @ 85:4e6757e8ccd4
New enhanced ImageLoader stuff.
Now uses Subsampling and image regions on read.
Now implements enhance, rotate and mirror for ImageLoader/Java2D
author | robcast |
---|---|
date | Thu, 27 Feb 2003 15:07:29 +0100 |
parents | 63c8186455c1 |
children | 997ba69afb81 |
comparison
equal
deleted
inserted
replaced
84:ed1b698b4f0a | 85:4e6757e8ccd4 |
---|---|
50 */ | 50 */ |
51 //public class Scaler extends HttpServlet implements SingleThreadModel { | 51 //public class Scaler extends HttpServlet implements SingleThreadModel { |
52 public class Scaler extends HttpServlet { | 52 public class Scaler extends HttpServlet { |
53 | 53 |
54 // digilib servlet version (for all components) | 54 // digilib servlet version (for all components) |
55 public static final String dlVersion = "1.6b"; | 55 public static final String dlVersion = "1.6b3"; |
56 | 56 |
57 // Utils instance with debuglevel | 57 // Utils instance with debuglevel |
58 Utils util; | 58 Utils util; |
59 // FileOps instance | 59 // FileOps instance |
60 FileOps fileOp; | 60 FileOps fileOp; |
329 + "ms"); | 329 + "ms"); |
330 return; | 330 return; |
331 } | 331 } |
332 | 332 |
333 // finally load the file | 333 // finally load the file |
334 docuImage.loadImage(fileToLoad); | 334 if (docuImage.isPreloadSupported()) { |
335 // only preload if supported | |
336 docuImage.preloadImage(fileToLoad); | |
337 } else { | |
338 docuImage.loadImage(fileToLoad); | |
339 } | |
335 | 340 |
336 /* | 341 /* |
337 * crop and scale the image | 342 * crop and scale the image |
338 */ | 343 */ |
339 | 344 |
346 2, | 351 2, |
347 "time " + (System.currentTimeMillis() - startTime) + "ms"); | 352 "time " + (System.currentTimeMillis() - startTime) + "ms"); |
348 | 353 |
349 // coordinates using Java2D | 354 // coordinates using Java2D |
350 // image size | 355 // image size |
351 Rectangle2D imgBounds = new Rectangle2D.Double(0, 0, imgWidth, imgHeight); | 356 Rectangle2D imgBounds = |
357 new Rectangle2D.Double(0, 0, imgWidth, imgHeight); | |
352 // user window area in 4-point form (ul, ur, ll, lr) | 358 // user window area in 4-point form (ul, ur, ll, lr) |
353 Point2D[] userAreaC = { | 359 Point2D[] userAreaC = |
354 new Point2D.Double(paramWX, paramWY), | 360 { |
355 new Point2D.Double(paramWX + paramWW, paramWY), | 361 new Point2D.Double(paramWX, paramWY), |
356 new Point2D.Double(paramWX, paramWY + paramWH), | 362 new Point2D.Double(paramWX + paramWW, paramWY), |
357 new Point2D.Double(paramWX + paramWW, paramWY + paramWH) | 363 new Point2D.Double(paramWX, paramWY + paramWH), |
358 }; | 364 new Point2D.Double(paramWX + paramWW, paramWY + paramWH)}; |
359 // transformation from relative [0,1] to image coordinates. | 365 // transformation from relative [0,1] to image coordinates. |
360 AffineTransform imgTrafo = new AffineTransform(); | 366 AffineTransform imgTrafo = new AffineTransform(); |
361 imgTrafo.scale(imgWidth, imgHeight); | 367 imgTrafo.scale(imgWidth, imgHeight); |
362 // rotate coordinates | 368 // rotate coordinates |
363 //imgTrafo.rotate(Math.toRadians(-paramROT)); | 369 //imgTrafo.rotate(Math.toRadians(-paramROT)); |
364 | 370 |
365 // coordinates and scaling | 371 // coordinates and scaling |
366 double areaXoff; | 372 double areaXoff; |
367 double areaYoff; | 373 double areaYoff; |
368 double areaWidth; | 374 double areaWidth; |
369 double areaHeight; | 375 double areaHeight; |
370 double scaleX; | 376 double scaleX; |
371 double scaleY; | 377 double scaleY; |
372 double scaleXY; | 378 double scaleXY; |
373 | 379 |
380 /* if (scaleToFit) { | |
381 // calculate absolute from relative coordinates | |
382 areaXoff = paramWX * imgWidth; | |
383 areaYoff = paramWY * imgHeight; | |
384 areaWidth = paramWW * imgWidth; | |
385 areaHeight = paramWH * imgHeight; | |
386 // calculate scaling factors | |
387 scaleX = paramDW / areaWidth * paramWS; | |
388 scaleY = paramDH / areaHeight * paramWS; | |
389 scaleXY = (scaleX > scaleY) ? scaleY : scaleX; | |
390 } else { | |
391 // crop to fit | |
392 // calculate absolute from relative coordinates | |
393 areaXoff = paramWX * imgWidth; | |
394 areaYoff = paramWY * imgHeight; | |
395 areaWidth = paramDW; | |
396 areaHeight = paramDH; | |
397 // calculate scaling factors | |
398 scaleX = 1f; | |
399 scaleY = 1f; | |
400 scaleXY = 1f; | |
401 } | |
402 | |
403 util.dprintln( | |
404 1, | |
405 "Scale " | |
406 + scaleXY | |
407 + "(" | |
408 + scaleX | |
409 + "," | |
410 + scaleY | |
411 + ") on " | |
412 + areaXoff | |
413 + "," | |
414 + areaYoff | |
415 + " " | |
416 + areaWidth | |
417 + "x" | |
418 + areaHeight); | |
419 */ | |
420 // Java2D | |
421 // area in image pixel coordinates | |
422 Point2D[] imgAreaC = { null, null, null, null }; | |
423 // transform user coordinate area to image coordinate area | |
424 imgTrafo.transform(userAreaC, 0, imgAreaC, 0, 4); | |
425 areaXoff = imgAreaC[0].getX(); | |
426 areaYoff = imgAreaC[0].getY(); | |
427 // calculate scaling factors | |
374 if (scaleToFit) { | 428 if (scaleToFit) { |
375 // calculate absolute from relative coordinates | 429 areaWidth = imgAreaC[0].distance(imgAreaC[1]); |
376 areaXoff = paramWX * imgWidth; | 430 areaHeight = imgAreaC[0].distance(imgAreaC[2]); |
377 areaYoff = paramWY * imgHeight; | |
378 areaWidth = paramWW * imgWidth; | |
379 areaHeight = paramWH * imgHeight; | |
380 // calculate scaling factors | |
381 scaleX = paramDW / areaWidth * paramWS; | 431 scaleX = paramDW / areaWidth * paramWS; |
382 scaleY = paramDH / areaHeight * paramWS; | 432 scaleY = paramDH / areaHeight * paramWS; |
383 scaleXY = (scaleX > scaleY) ? scaleY : scaleX; | 433 scaleXY = (scaleX > scaleY) ? scaleY : scaleX; |
384 } else { | 434 } else { |
385 // crop to fit | 435 // crop to fit |
386 // calculate absolute from relative coordinates | 436 areaWidth = paramDW * paramWS; |
387 areaXoff = paramWX * imgWidth; | 437 areaHeight = paramDH * paramWS; |
388 areaYoff = paramWY * imgHeight; | |
389 areaWidth = paramDW; | |
390 areaHeight = paramDH; | |
391 // calculate scaling factors | |
392 scaleX = 1f; | 438 scaleX = 1f; |
393 scaleY = 1f; | 439 scaleY = 1f; |
394 scaleXY = 1f; | 440 scaleXY = 1f; |
441 | |
395 } | 442 } |
396 | 443 |
397 util.dprintln( | 444 util.dprintln( |
398 1, | 445 1, |
399 "Scale " | 446 "Scale " |
409 + " " | 456 + " " |
410 + areaWidth | 457 + areaWidth |
411 + "x" | 458 + "x" |
412 + areaHeight); | 459 + areaHeight); |
413 | 460 |
414 // Java2D | |
415 Point2D[] imgAreaC = { null, null, null, null }; | |
416 | |
417 imgTrafo.transform(userAreaC, 0, imgAreaC, 0, 4); | |
418 areaXoff = imgAreaC[0].getX(); | |
419 areaYoff = imgAreaC[0].getY(); | |
420 areaWidth = imgAreaC[0].distance(imgAreaC[1]); | |
421 areaHeight = imgAreaC[0].distance(imgAreaC[2]); | |
422 Rectangle2D imgArea = | |
423 new Rectangle2D.Double( | |
424 areaXoff, | |
425 areaYoff, | |
426 areaWidth, | |
427 areaHeight); | |
428 // calculate scaling factors | |
429 scaleX = paramDW / areaWidth * paramWS; | |
430 scaleY = paramDH / areaHeight * paramWS; | |
431 scaleXY = (scaleX > scaleY) ? scaleY : scaleX; | |
432 | |
433 util.dprintln( | |
434 1, | |
435 "Scale " | |
436 + scaleXY | |
437 + "(" | |
438 + scaleX | |
439 + "," | |
440 + scaleY | |
441 + ") on " | |
442 + areaXoff | |
443 + "," | |
444 + areaYoff | |
445 + " " | |
446 + areaWidth | |
447 + "x" | |
448 + areaHeight); | |
449 | |
450 // clip area at the image border | 461 // clip area at the image border |
451 /* areaWidth = | 462 /* areaWidth = |
452 (areaXoff + areaWidth > imgWidth) | 463 (areaXoff + areaWidth > imgWidth) |
453 ? imgWidth - areaXoff | 464 ? imgWidth - areaXoff |
454 : areaWidth; | 465 : areaWidth; |
455 areaHeight = | 466 areaHeight = |
456 (areaYoff + areaHeight > imgHeight) | 467 (areaYoff + areaHeight > imgHeight) |
457 ? imgHeight - areaYoff | 468 ? imgHeight - areaYoff |
458 : areaHeight; | 469 : areaHeight; |
459 */ | 470 */ |
471 | |
472 // create new rectangle from coordinates | |
473 Rectangle2D imgArea = | |
474 new Rectangle2D.Double( | |
475 areaXoff, | |
476 areaYoff, | |
477 areaWidth, | |
478 areaHeight); | |
479 // clip area at the image border | |
460 imgArea = imgArea.createIntersection(imgBounds); | 480 imgArea = imgArea.createIntersection(imgBounds); |
461 areaWidth = imgArea.getWidth(); | 481 areaWidth = imgArea.getWidth(); |
462 areaHeight = imgArea.getHeight(); | 482 areaHeight = imgArea.getHeight(); |
463 | 483 |
464 util.dprintln( | 484 util.dprintln( |
465 2, | 485 2, |
466 "cropped: " | 486 "crop: " |
467 + areaXoff | 487 + areaXoff |
468 + "," | 488 + "," |
469 + areaYoff | 489 + areaYoff |
470 + " " | 490 + " " |
471 + areaWidth | 491 + areaWidth |
479 || (scaleXY * areaHeight < 2)) { | 499 || (scaleXY * areaHeight < 2)) { |
480 util.dprintln(1, "ERROR: invalid scale parameter set!"); | 500 util.dprintln(1, "ERROR: invalid scale parameter set!"); |
481 throw new ImageOpException("Invalid scale parameter set!"); | 501 throw new ImageOpException("Invalid scale parameter set!"); |
482 } | 502 } |
483 | 503 |
484 // crop and scale image | 504 /* |
485 docuImage.crop( | 505 * crop and scale image |
486 (int) areaXoff, | 506 */ |
487 (int) areaYoff, | 507 |
488 (int) areaWidth, | 508 // use subimage loading if possible |
489 (int) areaHeight); | 509 if (docuImage.isSubimageSupported()) { |
490 | 510 System.out.println( |
491 docuImage.scale(scaleXY); | 511 "Subimage: scale " + scaleXY + " = " + (1 / scaleXY)); |
512 double subf = 1d; | |
513 double subsamp = 1d; | |
514 if (scaleXY < 1) { | |
515 subf = 1 / scaleXY; | |
516 subsamp = Math.floor(subf); | |
517 scaleXY = subsamp / subf; | |
518 System.out.println( | |
519 "Using subsampling: " + subsamp + " rest " + scaleXY); | |
520 } | |
521 | |
522 docuImage.loadSubimage( | |
523 fileToLoad, | |
524 imgArea.getBounds(), | |
525 (int) subsamp); | |
526 | |
527 System.out.println( | |
528 "SUBSAMP: " | |
529 + subsamp | |
530 + " -> " | |
531 + docuImage.getWidth() | |
532 + "x" | |
533 + docuImage.getHeight()); | |
534 | |
535 docuImage.scale(scaleXY); | |
536 | |
537 } else { | |
538 docuImage.crop( | |
539 (int) areaXoff, | |
540 (int) areaYoff, | |
541 (int) areaWidth, | |
542 (int) areaHeight); | |
543 | |
544 docuImage.scale(scaleXY); | |
545 } | |
492 | 546 |
493 // mirror image | 547 // mirror image |
494 if (doMirror) { | 548 if (doMirror) { |
495 docuImage.mirror(mirrorAngle); | 549 docuImage.mirror(mirrorAngle); |
496 } | 550 } |
497 | 551 |
498 // rotate image (first shot :-) | 552 // rotate image (first shot :-) |
499 if (paramROT != 0) { | 553 if (paramROT != 0) { |
500 docuImage.rotate(paramROT); | 554 docuImage.rotate( |
555 paramROT); | |
501 } | 556 } |
502 | 557 |
503 // contrast and brightness enhancement | 558 // contrast and brightness enhancement |
504 if ((paramCONT != 0) || (paramBRGT != 0)) { | 559 if ((paramCONT != 0) || (paramBRGT != 0)) { |
505 double mult = Math.pow(2, paramCONT); | 560 double mult = Math.pow(2, paramCONT); |
506 docuImage.enhance(mult, paramBRGT); | 561 docuImage.enhance(mult, paramBRGT); |
507 } | 562 } |
508 | 563 |
509 util.dprintln( | 564 util.dprintln( |
510 2, | 565 2, |