/** * リサイズフィルタ */ package jp.crwdev.app.imagefilter; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.AreaAveragingScaleFilter; import java.awt.image.BufferedImage; import java.awt.image.FilteredImageSource; import java.awt.image.ImageFilter; import java.awt.image.ImageProducer; import com.mortennobel.imagescaling.ResampleOp; import jp.crwdev.app.interfaces.IImageFilter; public class ResizeFilter implements IImageFilter { /** リサイズ時のスケーリング係数W */ private double mResizedScaleW = 1.0f; /** リサイズ時のスケーリング係数H */ private double mResizedScaleH = 1.0f; /** * リサイズ時のスケーリング係数W を取得 * @return */ public double getResizedScaleW(){ return mResizedScaleW; } /** * リサイズ時のスケーリング係数H を取得 * @return */ public double getResizedScaleH(){ return mResizedScaleH; } @SuppressWarnings("unused") @Override public BufferedImage filter(BufferedImage image, ImageFilterParam param) { if(param == null || !param.isResize()){ return image; } /* * Scale */ int width = image.getWidth(); int height = image.getHeight(); Dimension maxSize = param.getResizeDimension(); Dimension resize = getResizeDimension(width, height, maxSize.width, maxSize.height); int rwidth = resize.width;//rect.width; int rheight = resize.height;//rect.height; double scalew = (double)rwidth/(double)width; double scaleh = (double)rheight/(double)height; mResizedScaleW = scalew; mResizedScaleH = scaleh; if(true){ ResampleOp resizeOp = new ResampleOp(rwidth, rheight); return resizeOp.filter(image, null); } else if(!param.isPreview() || true){ // 低速・高品質 ImageFilter filter = new AreaAveragingScaleFilter(rwidth, rheight); ImageProducer im = new FilteredImageSource(image.getSource(), filter); Image newImage = Toolkit.getDefaultToolkit().createImage(im); BufferedImage writeImage= new BufferedImage(rwidth, rheight, image.getType()); RenderingHints hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); hints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); Graphics2D g2Dimage = writeImage.createGraphics(); g2Dimage.setRenderingHints(hints); g2Dimage.drawImage(newImage, null, null); g2Dimage.dispose(); return writeImage; } else{ // 高速・低品質 AffineTransformOp atOp = null; atOp = new AffineTransformOp(AffineTransform.getScaleInstance(scalew, scaleh), AffineTransformOp.TYPE_BILINEAR); BufferedImage dest2 = new BufferedImage(rwidth, rheight, image.getType()); atOp.filter(image, dest2); return dest2; } } /** * リサイズ後の領域サイズを取得する * @param imgWidth 画像幅 * @param imgHeight 画像高さ * @param maxWidth 最大幅 * @param maxHeight 最大高さ * @return maxWidth/maxHeightに内接するサイズを返す。どちらもmaxに満たない場合は入力をそのまま返す */ public static Dimension getResizeDimension(int imgWidth, int imgHeight, int maxWidth, int maxHeight){ if(maxWidth >= imgWidth && maxHeight >= imgHeight){ return new Dimension(imgWidth, imgHeight); } if(imgHeight >= maxHeight){ int height = maxHeight; float aspect = (float)maxHeight/(float)imgHeight; int width = (int)((float)imgWidth * aspect); if(width > maxWidth){ width = maxWidth; aspect = (float)maxWidth/(float)imgWidth; height = (int)((float)imgHeight * aspect); return new Dimension(width,height); } return new Dimension(width,height); } else if(imgWidth >= maxWidth){ int width = maxWidth; float aspect = (float)maxWidth/(float)imgWidth; int height = (int)((float)imgHeight * aspect); if(height > maxHeight){ height = maxHeight; aspect = (float)maxHeight/(float)imgHeight; width = (int)((float)maxWidth * aspect); return new Dimension(width,height); } return new Dimension(width,height); } return new Dimension(imgWidth, imgHeight); } }