Mercurial > hg > digilib
view common/src/main/java/digilib/image/ImageWorker.java @ 1411:67134a81061b new_scaling
fixed black-last-pixel bug by rounding up scale factor in ImageLoaderDocuImage.scale().
added comments and formatting.
author | robcast |
---|---|
date | Tue, 20 Oct 2015 19:31:10 +0200 |
parents | 21441a3f5208 |
children | 8a713bc0e86f |
line wrap: on
line source
package digilib.image; /* * #%L * Worker (Callable) that renders an image. * %% * Copyright (C) 2010 - 2013 MPIWG Berlin * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * <http://www.gnu.org/licenses/lgpl-3.0.html>. * #L% * Author: Robert Casties (robcast@berlios.de) */ import java.awt.Rectangle; import java.io.IOException; import java.util.concurrent.Callable; import org.apache.log4j.Logger; import digilib.conf.DigilibConfiguration; import digilib.io.FileOpException; /** * Worker that renders an image. * * @author casties * */ public class ImageWorker implements Callable<DocuImage> { protected static Logger logger = Logger.getLogger(ImageWorker.class); private DigilibConfiguration dlConfig; private ImageJobDescription jobinfo; /** flag for stopping the thread */ private boolean stopNow = false; public ImageWorker(DigilibConfiguration dlConfig, ImageJobDescription jobinfo) { super(); this.dlConfig = dlConfig; this.jobinfo = jobinfo; } /** * render and return the image */ public DocuImage call() throws FileOpException, IOException, ImageOpException { logger.debug("ImageWorker starting"); long startTime = System.currentTimeMillis(); if (stopNow) { logger.debug("ImageWorker stopping (at the beginning)"); return null; } DocuImage docuImage = jobinfo.getDocuImage(); if (docuImage == null) { docuImage = DocuImageFactory.getInstance(); if (docuImage == null) { throw new ImageOpException("Unable to get DocuImage instance!"); } } // set interpolation quality docuImage.setQuality(jobinfo.getScaleQual()); // get area of interest and scale factor Rectangle loadRect = jobinfo.getOuterUserImgArea().getBounds(); double scaleXY = jobinfo.getScaleXY(); if (stopNow) { logger.debug("ImageWorker stopping (after setup)"); return null; } /* * load, crop and scale the image */ if (docuImage.isSubimageSupported()) { // use subimage loading if possible logger.debug("Subimage: scale " + scaleXY + " = " + (1 / scaleXY)); double subf = 1d; double subsamp = 1d; if (scaleXY < 1) { subf = 1 / scaleXY; // for higher quality reduce subsample factor by minSubsample if (jobinfo.getScaleQual() > 0) { subsamp = Math.max(Math.floor(subf / dlConfig.getAsFloat("subsample-minimum")), 1d); } else { subsamp = Math.floor(subf); } // correct scaling factor by subsampling factor scaleXY *= subsamp; logger.debug("Using subsampling: " + subsamp + " rest " + scaleXY); } // load region with subsampling docuImage.loadSubimage(jobinfo.getInput(), loadRect, (int) subsamp); logger.debug("SUBSAMP: " + subsamp + ": " + jobinfo.getInput().getSize() + " -> " + docuImage.getSize()); if (stopNow) { logger.debug("ImageWorker stopping (after loading and cropping)"); return null; } // and scale docuImage.scale(scaleXY, scaleXY); } else { // else load and crop the whole file docuImage.loadImage(jobinfo.getInput()); if (stopNow) { logger.debug("ImageWorker stopping (after loading)"); return null; } docuImage.crop((int) loadRect.getX(), (int) loadRect.getY(), (int) loadRect.getWidth(), (int) loadRect.getHeight()); if (stopNow) { logger.debug("ImageWorker stopping (after cropping)"); return null; } docuImage.scale(scaleXY, scaleXY); } if (stopNow) { logger.debug("ImageWorker stopping (after scaling)"); return null; } /* * mirror image * operation mode: "hmir": mirror horizontally, "vmir": mirror vertically */ if (jobinfo.hasOption("hmir")) { docuImage.mirror(0); } if (jobinfo.hasOption("vmir")) { docuImage.mirror(90); } if (stopNow) { logger.debug("ImageWorker stopping (after mirroring)"); return null; } /* * rotate image */ if (jobinfo.getAsFloat("rot") != 0d) { docuImage.rotate(jobinfo.getAsFloat("rot")); /* * if (jobinfo.get_wholeRotArea()) { // crop to the inner bounding * box float xcrop = (float) (docuImage.getWidth() - * jobinfo.get_innerUserImgArea().getWidth() scaleXY); float ycrop = * (float) (docuImage.getHeight() - * jobinfo.get_innerUserImgArea().getHeight() scaleXY); if ((xcrop > * 0) || (ycrop > 0)) { // only crop smaller xcrop = (xcrop > 0) ? * xcrop : 0; ycrop = (ycrop > 0) ? ycrop : 0; // crop image * docuImage.crop((int) (xcrop / 2), (int) (ycrop / 2), (int) * (docuImage.getWidth() - xcrop), (int) (docuImage.getHeight() - * ycrop)); } } */ } if (stopNow) { logger.debug("ImageWorker stopping (after rotating)"); return null; } /* * color modification */ float[] paramRGBM = jobinfo.getRGBM(); float[] paramRGBA = jobinfo.getRGBA(); if ((paramRGBM != null) || (paramRGBA != null)) { // make sure we actually have two arrays if (paramRGBM == null) { paramRGBM = new float[3]; } if (paramRGBA == null) { paramRGBA = new float[3]; } // calculate "contrast" values (c=2^x) float[] mult = new float[3]; for (int i = 0; i < 3; i++) { mult[i] = (float) Math.pow(2, (float) paramRGBM[i]); } docuImage.enhanceRGB(mult, paramRGBA); } if (stopNow) { logger.debug("ImageWorker stopping (after enhanceRGB)"); return null; } /* * contrast and brightness enhancement */ float paramCONT = jobinfo.getAsFloat("cont"); float paramBRGT = jobinfo.getAsFloat("brgt"); if ((paramCONT != 0f) || (paramBRGT != 0f)) { float mult = (float) Math.pow(2, paramCONT); docuImage.enhance(mult, paramBRGT); } if (stopNow) { logger.debug("ImageWorker stopping (after enhance)"); return null; } /* * color operation */ DocuImage.ColorOp colop = jobinfo.getColOp(); if (colop != null) { docuImage.colorOp(colop); } logger.debug("rendered in " + (System.currentTimeMillis() - startTime) + "ms"); return docuImage; } /** * Set the stopNow flag. Thread stops at the next occasion. */ public void stopNow() { this.stopNow = true; } }