All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.image.AbstractBufferedImageOp Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2012 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package com.day.image;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.util.Map;

/**
 * The AbstractBufferedImageOp provides a basic implementation to
 * implement the BufferedImageOp interface. Basically this
 * abstract class deals with all the intricacies of make the images compatible
 * with operations on each other.
 * 

* The most easy use of this class is to simply implement an appropriate * constructor and {@link #doFilter(BufferedImage, BufferedImage)} method. Other * methods need not be overwritten unless special needs arise. See the method's * documentations for more information. * * @version $Revision$ * @author fmeschbe * @since coati * @audience wad */ public abstract class AbstractBufferedImageOp implements BufferedImageOp { /** The rendering hints for color model adaption */ protected final RenderingHints hints; /** * Sets the internal fields of this abstract base class. * * @param hints The rendering hints. May be null. The hints * are copied to a new object. Thus modifying the object after * a call to this method does not modify the internal hints * object. */ protected AbstractBufferedImageOp(RenderingHints hints) { this.hints = hints == null ? null : new RenderingHints((Map) hints); } //---------- BufferedImageOp interface ------------------------------------- /** * Performs the operation on a BufferedImage. This implementation only cares * to make the images compatible and calls the * {@link #doFilter(BufferedImage, BufferedImage)} to do the actual * filtering operation. *

* If the color models for the two images do not match, a color * conversion into the destination color model will be performed. * If the destination image is null, * a BufferedImage with an appropriate ColorModel will be created. *

* Note: The dest image might be clipped if it is not big enough to take * the complete resized image. *

* Note: Extensions to this class should not need to overwrite this method. * * @param src The src image to be operated upon. * @param dst The dest image into which to place the modified image. This * may be null in which case a new image with the * correct size will be created. * * @return The newly created image (if dest was null) or dest * into which the resized src image has been drawn. * * @throws IllegalArgumentException if the dest image is the same as the * src image. * @throws NullPointerException if the src image is null. */ public BufferedImage filter(BufferedImage src, BufferedImage dst) { if (src == null) { throw new NullPointerException("src image is null"); } if (src == dst) { throw new IllegalArgumentException("src image cannot be the "+ "same as the dst image"); } boolean needToConvert = false; ColorModel srcCM = src.getColorModel(); ColorModel dstCM; BufferedImage origDst = dst; // Can't convolve an IndexColorModel. Need to expand it if (srcCM instanceof IndexColorModel) { IndexColorModel icm = (IndexColorModel) srcCM; src = icm.convertToIntDiscrete(src.getRaster(), true); srcCM = src.getColorModel(); } if (dst == null) { dst = createCompatibleDestImage(src, null); dstCM = srcCM; origDst = dst; } else { dstCM = dst.getColorModel(); if (srcCM.getColorSpace().getType() != dstCM.getColorSpace().getType()) { needToConvert = true; dst = createCompatibleDestImage(src, null); dstCM = dst.getColorModel(); } else if (dstCM instanceof IndexColorModel) { dst = createCompatibleDestImage(src, null); dstCM = dst.getColorModel(); } } doFilter(src, dst); if (needToConvert) { ColorConvertOp ccop = new ColorConvertOp(hints); ccop.filter(dst, origDst); } else if (origDst != dst) { Graphics2D g = origDst.createGraphics(); try { g.drawImage(dst, 0, 0, null); } finally { g.dispose(); } } return origDst; } /** * Returns the bounding box of the filtered destination image. This * implementation returns the bounding box of the source image given. This * method is likely to be overwritten by extending classes which implement * filtering operation resulting in the change of the image size. *

* The IllegalArgumentException may be thrown if the source * image is incompatible with the types of images allowed * by the class implementing this filter. */ public Rectangle2D getBounds2D(BufferedImage src) { return src.getRaster().getBounds(); } /** * Creates a zeroed destination image with the correct size and number of * bands. This calls {@link #getBounds2D(BufferedImage)} to decide on the * size of the new image. So this method needs only be overwritten by * extending class, which need more specialized operations than just to * create a new image with the correct size and color model. *

* The IllegalArgumentException may be thrown if the source * image is incompatible with the types of images allowed * by the class implementing this filter. * * @param src Source image for the filter operation. * @param destCM ColorModel of the destination. If null, the * ColorModel of the source will be used. */ public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) { Rectangle2D bounds = getBounds2D(src); int w = (int) (bounds.getWidth()); int h = (int) (bounds.getHeight()); BufferedImage image; if (destCM == null) { destCM = src.getColorModel(); // Not much support for ICM if (destCM instanceof IndexColorModel) { destCM = ColorModel.getRGBdefault(); } } image = new BufferedImage (destCM, destCM.createCompatibleWritableRaster(w, h), destCM.isAlphaPremultiplied(), null); return image; } /** * Returns the location of the destination point given a * point in the source image. If dstPt is non-null, it * will be used to hold the return value. This method is likely to be * overwritten by extending classes which implement filtering operation * resulting in the change of the image size or in rotated images. */ public Point2D getPoint2D(Point2D srcPt, Point2D dstPt) { if (dstPt == null) { dstPt = (Point2D)srcPt.clone(); } else { dstPt.setLocation(srcPt); } return dstPt; } /** * Returns a copy of the rendering hints for this BufferedImageOp. Returns * null if no hints have been set. Modyfing the object returned does not * modify the rendering hints set on this. * * @return The rendering hints of this or null if none are * defined. */ public final RenderingHints getRenderingHints() { return hints == null ? null : new RenderingHints((Map) hints); } //---------- protected ----------------------------------------------------- /** * Implements the filter algorithm. This method is called by the * {@link #filter(BufferedImage, BufferedImage)} method to execute the * implementation's special filtering. *

* Implementations are guaranteed that the source and the destination image * are not the same and neither of the images is null. * * @param src The srouce image to be operated upon. * @param dst The destination image getting the resulting image. This must * not be null. */ protected abstract void doFilter(BufferedImage src, BufferedImage dst); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy