/* * Copyright 2013, Morten Nobel-Joergensen * * License: The BSD 3-Clause License * http://opensource.org/licenses/BSD-3-Clause */ package com.mortennobel.imagescaling; import com.jhlabs.image.UnsharpFilter; import java.awt.*; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ColorModel; import java.util.ArrayList; import java.util.List; /** * @author Morten Nobel-Joergensen */ public abstract class AdvancedResizeOp implements BufferedImageOp { public static enum UnsharpenMask{ None(0), Soft(0.15f), Normal(0.3f), VerySharp(0.45f), Oversharpened(0.60f); private final float factor; UnsharpenMask(float factor) { this.factor = factor; } } private List<ProgressListener> listeners = new ArrayList<ProgressListener>(); private final DimensionConstrain dimensionConstrain; private UnsharpenMask unsharpenMask = UnsharpenMask.None; public AdvancedResizeOp(DimensionConstrain dimensionConstrain) { this.dimensionConstrain = dimensionConstrain; } public UnsharpenMask getUnsharpenMask() { return unsharpenMask; } public void setUnsharpenMask(UnsharpenMask unsharpenMask) { this.unsharpenMask = unsharpenMask; } protected void fireProgressChanged(float fraction){ for (ProgressListener progressListener:listeners){ progressListener.notifyProgress(fraction); } } public final void addProgressListener(ProgressListener progressListener) { listeners.add(progressListener); } public final boolean removeProgressListener(ProgressListener progressListener) { return listeners.remove(progressListener); } public final BufferedImage filter(BufferedImage src, BufferedImage dest){ Dimension dstDimension = dimensionConstrain.getDimension(new Dimension(src.getWidth(),src.getHeight())); int dstWidth = dstDimension.width; int dstHeight = dstDimension.height; BufferedImage bufferedImage = doFilter(src, dest, dstWidth, dstHeight); if (unsharpenMask!= UnsharpenMask.None){ UnsharpFilter unsharpFilter= new UnsharpFilter(); unsharpFilter.setRadius(2f); unsharpFilter.setAmount(unsharpenMask.factor); unsharpFilter.setThreshold(10); return unsharpFilter.filter(bufferedImage, null); } return bufferedImage; } protected abstract BufferedImage doFilter(BufferedImage src, BufferedImage dest, int dstWidth, int dstHeight); /** * {@inheritDoc} */ public final Rectangle2D getBounds2D(BufferedImage src) { return new Rectangle(0, 0, src.getWidth(), src.getHeight()); } /** * {@inheritDoc} */ public final BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) { if (destCM == null) { destCM = src.getColorModel(); } return new BufferedImage(destCM, destCM.createCompatibleWritableRaster( src.getWidth(), src.getHeight()), destCM.isAlphaPremultiplied(), null); } /** * {@inheritDoc} */ public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) { return (Point2D) srcPt.clone(); } /** * {@inheritDoc} */ public final RenderingHints getRenderingHints() { return null; } }