org.richfaces.resource.Java2DAnimatedUserResourceWrapperImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of richfaces-core Show documentation
Show all versions of richfaces-core Show documentation
The RichFaces core framework.
The newest version!
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This 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 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.richfaces.resource;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Iterator;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
import org.w3c.dom.Node;
/**
* @author Nick Belaevski
*
*/
public class Java2DAnimatedUserResourceWrapperImpl extends Java2DUserResourceWrapperImpl {
public Java2DAnimatedUserResourceWrapperImpl(Java2DAnimatedUserResource resourceObject, boolean cacheable, boolean versioned) {
super(resourceObject, cacheable, versioned);
}
private static ImageWriter getSequenceCapableImageWriter(ImageType imageType) {
Iterator imageWriters = ImageIO.getImageWritersByFormatName(imageType.getFormatName());
while (imageWriters.hasNext()) {
ImageWriter imageWriter = imageWriters.next();
if (imageWriter.canWriteSequence()) {
return imageWriter;
}
}
throw new IllegalArgumentException(MessageFormat.format("Cannot find sequence-capable image writer for {0} format",
imageType.getFormatName()));
}
private static Node getOrCreateChild(Node root, String name) {
Node result = null;
for (Node node = root.getFirstChild(); (node != null) && (result == null); node = node.getNextSibling()) {
if (name.equals(node.getNodeName())) {
result = node;
}
}
if (result == null) {
result = new IIOMetadataNode(name);
root.appendChild(result);
}
return result;
}
private static void checkSupportedFormat(ImageType imageType) {
if (imageType != ImageType.GIF) {
throw new IllegalArgumentException(MessageFormat.format("Image format {0} is not supported",
imageType.getFormatName()));
}
}
@Override
public String getRequestPath() {
// detect unsupported types early
checkSupportedFormat(getWrapped().getImageType());
return super.getRequestPath();
}
@Override
protected void paintAndWrite(ImageOutputStream outputStream) throws IOException {
Java2DAnimatedUserResource userResource = (Java2DAnimatedUserResource) getWrapped();
ImageType imageType = userResource.getImageType();
checkSupportedFormat(imageType);
ImageWriter imageWriter = getSequenceCapableImageWriter(imageType);
Dimension dimension = userResource.getDimension();
BufferedImage image = imageType.createImage(dimension);
try {
imageWriter.setOutput(outputStream);
ImageWriteParam defaultImageWriteParam = imageWriter.getDefaultWriteParam();
IIOMetadata imageMetaData = imageWriter.getDefaultImageMetadata(
ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB), defaultImageWriteParam);
String metaFormatName = imageMetaData.getNativeMetadataFormatName();
Node root = imageMetaData.getAsTree(metaFormatName);
IIOMetadataNode graphicsControlExtensionNode = (IIOMetadataNode) getOrCreateChild(root, "GraphicControlExtension");
// http://java.sun.com/javase/6/docs/api/javax/imageio/metadata/doc-files/gif_metadata.html
graphicsControlExtensionNode.setAttribute("disposalMethod", "none");
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
graphicsControlExtensionNode.setAttribute("transparentColorFlag", "FALSE");
graphicsControlExtensionNode.setAttribute("delayTime", Integer.toString(userResource.getFrameDelay() / 100));
graphicsControlExtensionNode.setAttribute("transparentColorIndex", "0");
Node applicationExtensionsNode = getOrCreateChild(root, "ApplicationExtensions");
IIOMetadataNode netscapeExtension = new IIOMetadataNode("ApplicationExtension");
netscapeExtension.setAttribute("applicationID", "NETSCAPE");
netscapeExtension.setAttribute("authenticationCode", "2.0");
byte numLoops = (byte) (userResource.isLooped() ? 0x0 : 0x1);
netscapeExtension.setUserObject(new byte[] { 0x1, numLoops, 0x0 });
applicationExtensionsNode.appendChild(netscapeExtension);
imageMetaData.setFromTree(metaFormatName, root);
imageWriter.prepareWriteSequence(null);
userResource.startFramesSequence();
while (userResource.hasNextFrame()) {
Graphics2D g2d = null;
try {
g2d = createGraphics(image);
userResource.paint(g2d);
imageWriter.writeToSequence(new IIOImage(image, null, imageMetaData), defaultImageWriteParam);
} finally {
if (g2d != null) {
g2d.dispose();
}
}
}
imageWriter.endWriteSequence();
} finally {
imageWriter.dispose();
}
}
}