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,