Mercurial > hg > digilib
changeset 1590:bd71cb53e1a3
fix rounding bug with mo=crop and mo=fill. added tests for crop and fill.
author | robcast |
---|---|
date | Wed, 08 Feb 2017 17:28:02 +0100 |
parents | 6892f39c1fdb |
children | 8dff61ffdbc3 |
files | common/src/main/java/digilib/image/ImageJobDescription.java webapp/src/test/java/digilib/servlet/ScalerTest.java |
diffstat | 2 files changed, 61 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/common/src/main/java/digilib/image/ImageJobDescription.java Wed Feb 08 14:52:46 2017 +0100 +++ b/common/src/main/java/digilib/image/ImageJobDescription.java Wed Feb 08 17:28:02 2017 +0100 @@ -262,7 +262,7 @@ /* * crop to fit -- don't scale */ - imgArea = prepareCropToFit(); + imgArea = prepareClipToFit(); } else if (isAbsoluteScale()) { /* @@ -280,6 +280,7 @@ * Scale to fit: scale factor based on destination size dw/dh and user area. * * Uses a uniform scale factor for x and y. + * * Sets ScaleX and ScaleY. */ protected Rectangle2D prepareScaleToFit() throws IOException { @@ -327,21 +328,25 @@ if (scaleX > scaleY) { scaleY = scaleX; // crop mode uses whole destination rect - long croppedAreaHeight = (long) (getDh() / scaleY); + long croppedAreaHeight = Math.round(getDh() / scaleY); if (areaHeight > croppedAreaHeight) { // center cropped area areaY += (areaHeight - croppedAreaHeight) / 2; } areaHeight = croppedAreaHeight; + // re-compute scaleY + scaleY = getDh() / (double) areaHeight; } else { scaleX = scaleY; // crop mode uses whole destination rect - long croppedAreaWidth = (long) (getDw() / scaleX); + long croppedAreaWidth = Math.round(getDw() / scaleX); if (areaWidth > croppedAreaWidth) { // center cropped area areaX += (areaWidth - croppedAreaWidth) / 2; } areaWidth = croppedAreaWidth; + // re-compute scaleX + scaleX = getDw() / (double) areaWidth; } } else { // use the smaller factor to get fit-in-box @@ -349,23 +354,27 @@ scaleX = scaleY; if (hasOption("fill")) { // fill mode uses whole destination rect - long filledAreaWidth = (long) (getDw() / scaleX); + long filledAreaWidth = Math.round(getDw() / scaleX); if (filledAreaWidth > areaWidth) { // center filled area areaX -= (filledAreaWidth - areaWidth) / 2; } areaWidth = filledAreaWidth; + // re-compute scaleX + scaleX = getDw() / (double) areaWidth; } } else { scaleY = scaleX; if (hasOption("fill")) { // fill mode uses whole destination rect - long filledAreaHeight = (long) (getDh() / scaleY); + long filledAreaHeight = Math.round(getDh() / scaleY); if (filledAreaHeight > areaHeight) { // center filled area areaY -= (filledAreaHeight - areaHeight) / 2; } areaHeight = filledAreaHeight; + // re-compute scaleY + scaleY = getDh() / (double) areaHeight; } } } @@ -376,7 +385,8 @@ /** * Squeeze to fit: scale factor based on destination size and user area. * - * Uses separate scale factors for x and y + * Uses separate scale factors for x and y to fill destination size changing aspect ratio. + * * Sets ScaleX and ScaleY. */ protected Rectangle2D prepareSqueezeToFit() throws IOException { @@ -419,7 +429,9 @@ * Absolute scale factor: either original size, based on dpi, or absolute. * * Uses a uniform scale factor for x and y. + * * Sets ScaleX and ScaleY. + * * @throws ImageOpException */ protected Rectangle2D prepareAbsoluteScale() throws IOException, ImageOpException { @@ -502,11 +514,11 @@ /** - * Crop to fit: don't scale. + * Clip to fit: don't scale. * - * Sets ScaleX and ScaleY. + * Sets ScaleX and ScaleY to 1.0. */ - protected Rectangle2D prepareCropToFit() throws IOException { + protected Rectangle2D prepareClipToFit() throws IOException { /* * minimum source size = hires size */ @@ -789,6 +801,8 @@ /** * Return the size of the selected input image. * + * Note: may use getMinSourceSize(). + * * @return * @throws IOException */
--- a/webapp/src/test/java/digilib/servlet/ScalerTest.java Wed Feb 08 14:52:46 2017 +0100 +++ b/webapp/src/test/java/digilib/servlet/ScalerTest.java Wed Feb 08 17:28:02 2017 +0100 @@ -108,18 +108,38 @@ } /** - * Test scaling with mo=fit + * Test scaling with mo=fit. + * + * Fit selected area to destination image width, staying below destination image height. + * * @throws Exception */ @Test - public void testScaleFit() throws Exception { + public void testScaleFitWidth() throws Exception { BufferedImage img = loadImage("ww=0.0836&wh=0.0378&wx=0&wy=0.961&dw=173&dh=235&mo=fit,errcode", null); assertEquals("height", 125, img.getHeight()); assertEquals("width", 173, img.getWidth()); } /** - * Test scaling with mo=squeeze + * Test scaling with mo=fill. + * + * Fit selected area to destination image width, expanding area to destination image height. + * + * @throws Exception + */ + @Test + public void testScaleFillHeight() throws Exception { + BufferedImage img = loadImage("ww=0.0836&wh=0.0378&wx=0.0833&wy=0.9224&dw=173&dh=235&mo=fill,errcode", null); + assertEquals("height", 235, img.getHeight()); + assertEquals("width", 173, img.getWidth()); + } + + /** + * Test scaling with mo=squeeze. + * + * Fit selected area to destination image width and height by changing aspect ratio. + * * @throws Exception */ @Test @@ -130,6 +150,19 @@ } /** + * Test scaling with mo=crop. + * + * + * @throws Exception + */ + @Test + public void testScaleCrop() throws Exception { + BufferedImage img = loadImage("ww=0.0836&wh=0.0378&wx=0&wy=0.961&dw=173&dh=235&mo=fit,errcode", null); + assertEquals("height", 125, img.getHeight()); + assertEquals("width", 173, img.getWidth()); + } + + /** * Test scaling with mo=clip * @throws Exception */ @@ -152,7 +185,7 @@ } /** - * Test forced image type with mo=jpg + * Test content-type and pixel color of forced image type with mo=jpg * @throws Exception */ @Test @@ -163,7 +196,7 @@ } /** - * Test forced image type with mo=png + * Test content-type and pixel color of forced image type with mo=png * @throws Exception */ @Test