com.day.image.StampOp Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/*************************************************************************
*
* 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.AlphaComposite;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
/**
* The StampOp
is an image operation, which may scale the source
* image to the destination image and put a stamp mark ontop of the (scaled)
* destination image. The location and size as well as the mark it self must be
* provided to the operation before the filter
method is called.
* The operation can be reused to stamp multiple images.
*
* Sample use:
*
*
* // create op with no rendering hints
* StampOp op = new StampOp();
*
* // set the stamp image
* op.setStamp(watermarkImage);
*
* // set the top,left location, default is (0, 0)
* op.setStampLocation(20, 20);
*
* // set the stamp size, default is (15, 15)
* op.setStampSize(30, 30);
*
* // draw stamp with 50% opacity (default is 100% opacity)
* op.setStampComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.5f));
*
* // apply the stamp
* stampedImage = op.filter(rawImage, null);
*
*/
public class StampOp extends AbstractBufferedImageOp {
/**
* The image to stamp of the source in doFilter
*
* @see #setStamp(BufferedImage)
* @see #getStamp()
*/
private BufferedImage stamp;
/**
* The cached stamp image. When calling the {@link #getSizedStamp()} method
* the original stamp image may be resized according to the dimension of the
* {@link #getStampPosition()} rectangle. To improve performance while
* reusing the same stamp and dimension the resized stamp is cached in this
* field.
*
* @see #setStampSize(int, int)
* @see #setStamp(BufferedImage)
*/
private volatile BufferedImage stampCache;
/**
* The position at which to place the stamp. X and Y coordinate definethe
* upper left corner relative to the source image. The width and height
* values define the size of the stamp and are used to adjust the size of
* the stamp image to the requested size.
*
* @see #setStampLocation(int, int)
* @see #setStampSize(int, int)
* @see #getStampPosition()
*/
private Rectangle2D stampPosition = new Rectangle2D.Double(0, 0, 15, 15);
/**
* The Composite defining how the stamp is painted over the source image the
* default value is to paint the stamp over the source image with full
* opacity.
*
* @see #setStampComposite(Composite)
* @see #getStampComposite()
*/
private Composite stampComposite = AlphaComposite.Src;
/**
* Creates an instance of this operation with the given rendering hints.
*
* @param hints The rendering hints to apply for the filter operation. This
* may be null
.
*/
public StampOp(RenderingHints hints) {
super(hints);
}
/**
* Creates an instance of this operation with no rendering hints.
*/
public StampOp() {
super(null);
}
/**
* Sets the stamp image. If this is null
, the operation does
* nothing else than copying the source image into the destination image.
*/
public void setStamp(BufferedImage stamp) {
this.stamp = stamp;
this.stampCache = null;
}
/**
* Returns the stamp image or null
if it has not yet been set.
*/
public BufferedImage getStamp() {
return stamp;
}
/**
* Sets the top, left location of the stamp.
*/
public void setStampLocation(int x, int y) {
this.stampPosition.setRect(x, y, stampPosition.getWidth(),
stampPosition.getHeight());
}
/**
* Sets the width and height of the stamp to be drawn.
*/
public void setStampSize(int width, int height) {
this.stampPosition.setRect(stampPosition.getX(), stampPosition.getY(),
width, height);
this.stampCache = null;
}
/**
* Returns the stamp location and size as a rectangle whose x and y fields
* define the top,left position and the width and height of the rectangle
* define the width and height of the stamp.
*/
public Rectangle2D getStampPosition() {
return stampPosition;
}
/**
* Sets the Composite
used to draw the stamp on the image. The
* default value is AlphaComposite.Src
which draws the stamp
* with full opacity.
*
* @param stampComposite The Composite
. If this is
* null
the current composite is not replaced.
*/
public void setStampComposite(Composite stampComposite) {
if (stampComposite != null) {
this.stampComposite = stampComposite;
}
}
/**
* Returns the current composite used to draw the image.
*/
public Composite getStampComposite() {
return stampComposite;
}
/**
* Applies the stamp on the source image. If the src image is equal to the
* destination image, the stamp is drawn on the original image thus
* modifying the src image. Otherwise the source image is first copied to
* the destination, optionally resizing if the destination has a different
* size. If the destination image is null
a new image with the
* same size and color setup as the source image is created to draw the
* source image and stamp.
*/
@Override
public BufferedImage filter(BufferedImage src, BufferedImage dst) {
// allow this filter operation on src and dst being the same
if (src == dst && src != null) {
doFilter(src, dst);
return dst;
}
return super.filter(src, dst);
}
protected void doFilter(BufferedImage src, BufferedImage dst) {
// paint the original image into the new destination first
Graphics2D gDst = dst.createGraphics();
// Optionally resize the src image while copying
if (src.getHeight() != dst.getHeight()
|| src.getWidth() != dst.getWidth()) {
ResizeOp sizer = new ResizeOp(dst.getWidth() / src.getWidth(),
dst.getHeight() / src.getHeight(), getRenderingHints());
sizer.filter(src, dst);
} else if (src != dst) {
// paint src into dst (size are the same)
gDst.drawRenderedImage(src, new AffineTransform());
}
// now paint the stamp on it applying the composite
BufferedImage stamp = getSizedStamp();
if (stamp != null) {
Composite oldComposite = gDst.getComposite();
gDst.setComposite(getStampComposite());
gDst.drawImage(stamp, (int) getStampPosition().getX(),
(int) getStampPosition().getY(), null);
gDst.setComposite(oldComposite);
}
}
// Returns the stamp image scaled to the desired stamp size
private BufferedImage getSizedStamp() {
if (stampCache == null) {
BufferedImage stamp = getStamp();
if (stamp != null) {
// check whether we have to resize
Rectangle2D stampPosition = getStampPosition();
double stampWidth = stamp.getWidth();
double stampHeight = stamp.getHeight();
if (stampPosition.getWidth() == stampWidth
&& stampPosition.getHeight() == stampHeight) {
stampCache = stamp;
} else {
// have to resize
double scaleX = stampPosition.getWidth() / stampWidth;
double scaleY = stampPosition.getHeight() / stampHeight;
ResizeOp stampSizer = new ResizeOp(scaleX, scaleY,
getRenderingHints());
stampCache = stampSizer.filter(stamp, null);
}
}
}
return stampCache;
}
}