/*
* Copyright 1999-2101 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.simpleimage;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.awt.image.WritableRenderedImage;
import javax.media.jai.PlanarImage;
import javax.media.jai.RenderedImageAdapter;
import javax.media.jai.WritableRenderedImageAdapter;
import org.w3c.dom.Node;
import com.alibaba.simpleimage.util.NodeUtils;
/**
* 这个类存在的意义在于可以比BufferedImage和PlanarImage提供更多的图片的源信息,同时可以保存像GIF这样多副图片的图片格式。 比如说可以保存JPEG的quality,采样参数等
* 对于PNG,BMP和GIF这三类无损压缩的图片格式,quality并没有意义 这里设置为93只是表示,这三类图片一旦按JPEG格式保存的话,默认的quality是93
*
* @author wendell
*/
public class ImageWrapper extends MetadataRenderedImage {
public static final int DEFAULT_QUALITY = 93;
protected RenderedImage[] images;
// only support jpeg broken indicator
protected boolean broken;
public ImageWrapper(BufferedImage bi){
this(bi, DEFAULT_QUALITY, false);
}
public ImageWrapper(PlanarImage img){
this(img, DEFAULT_QUALITY, false);
}
public ImageWrapper(BufferedImage bi, boolean isBroken){
this(bi, DEFAULT_QUALITY, isBroken);
}
public ImageWrapper(PlanarImage img, boolean isBroken){
this(img, DEFAULT_QUALITY, isBroken);
}
public ImageWrapper(BufferedImage bi, int quality){
this(bi, quality, false);
}
public ImageWrapper(BufferedImage bi, int quality, boolean isBroken){
this.quality = quality;
this.images = new RenderedImage[1];
this.images[0] = PlanarImage.wrapRenderedImage(bi);
this.broken = isBroken;
}
public ImageWrapper(PlanarImage image, int quality){
this(image, quality, false);
}
public ImageWrapper(PlanarImage image, int quality, boolean isBroken){
this.images = new RenderedImage[1];
this.images[0] = image;
this.quality = quality;
this.broken = isBroken;
}
public ImageWrapper(BufferedImage[] imgs){
setImages(imgs);
this.quality = DEFAULT_QUALITY;
}
public ImageWrapper(PlanarImage[] imgs){
setImages(imgs);
this.quality = DEFAULT_QUALITY;
}
public BufferedImage getAsBufferedImage(int index) {
if (images[index] instanceof BufferedImage) {
return (BufferedImage) images[index];
} else if (images[index] instanceof PlanarImage) {
return ((PlanarImage) images[index]).getAsBufferedImage();
} else if (images[index] instanceof WritableRenderedImage) {
return new WritableRenderedImageAdapter((WritableRenderedImage) images[index]).getAsBufferedImage();
} else {
return new RenderedImageAdapter(images[index]).getAsBufferedImage();
}
}
public BufferedImage getAsBufferedImage() {
return getAsBufferedImage(0);
}
public PlanarImage getAsPlanarImage(int index) {
if (images[index] instanceof PlanarImage) {
return (PlanarImage) images[index];
} else if (images[index] instanceof BufferedImage) {
return PlanarImage.wrapRenderedImage(images[index]);
} else {
return new RenderedImageAdapter(images[index]);
}
}
public PlanarImage getAsPlanarImage() {
return getAsPlanarImage(0);
}
public BufferedImage[] getAsBufferedImages() {
BufferedImage[] imgs = new BufferedImage[images.length];
for (int i = 0; i < imgs.length; i++) {
imgs[i] = getAsBufferedImage(i);
}
return imgs;
}
public PlanarImage[] getAsPlanarImages() {
PlanarImage[] imgs = new PlanarImage[images.length];
for (int i = 0; i < imgs.length; i++) {
imgs[i] = getAsPlanarImage(i);
}
return imgs;
}
public void setImages(BufferedImage[] imgs) {
images = new RenderedImage[imgs.length];
for (int i = 0; i < imgs.length; i++) {
images[i] = imgs[i];
}
}
public void setImages(PlanarImage[] imgs) {
images = new RenderedImage[imgs.length];
for (int i = 0; i < imgs.length; i++) {
images[i] = imgs[i];
}
}
public void setImage(int index, BufferedImage bi) {
this.images[index] = bi;
}
public void setImage(BufferedImage bi) {
setImage(0, bi);
}
public void setImage(int index, PlanarImage img) {
this.images[index] = img;
}
public void setImage(PlanarImage img) {
setImage(0, img);
}
public int getNumOfImages() {
return images.length;
}
/**
* 如果是除GIF以外的图片,getWidth()与getWidth(0)等价,既返回第一张图片的宽度 如果是GIF,则读取GIF的元信息来获取图片宽度,这个值不一定和getWidth(0)相等
*
* @return 图片宽度
*/
public int getWidth() {
if (format == ImageFormat.GIF && streamMetadata != null) {
Node screenDescNode = NodeUtils.getChild(streamMetadata, "LogicalScreenDescriptor");
if (screenDescNode != null) {
return NodeUtils.getIntAttr(screenDescNode, "logicalScreenWidth");
}
}
return getWidth(0);
}
/**
* 如果是除GIF以外的图片,getHeight()与getHeight(0)等价,既返回第一张图片的宽度 如果是GIF,则读取GIF的元信息来获取图片高度,这个值不一定和getHeight(0)相等
*
* @return 图片高度
*/
public int getHeight() {
if (format == ImageFormat.GIF && streamMetadata != null) {
Node screenDescNode = NodeUtils.getChild(streamMetadata, "LogicalScreenDescriptor");
if (screenDescNode != null) {
return NodeUtils.getIntAttr(screenDescNode, "logicalScreenHeight");
}
}
return getHeight(0);
}
public int getWidth(int index) {
if (index < 0 || index >= images.length) {
throw new IndexOutOfBoundsException("Just totally have " + images.length + " images");
}
return images[index].getWidth();
}
public int getHeight(int index) {
if (index < 0 || index >= images.length) {
throw new IndexOutOfBoundsException("Just totally have " + images.length + " images");
}
return images[index].getHeight();
}
@Override
public Object clone() throws CloneNotSupportedException {
int numOfImages = images.length;
BufferedImage[] imgs = new BufferedImage[numOfImages];
for (int i = 0; i < numOfImages; i++) {
PlanarImage oldImg = getAsPlanarImage(i);
imgs[i] = oldImg.getAsBufferedImage();
}
ImageWrapper newImgWrapper = new ImageWrapper(imgs);
newImgWrapper.quality = quality;
newImgWrapper.broken = broken;
newImgWrapper.format = format;
if (horizontalSamplingFactors != null) {
newImgWrapper.horizontalSamplingFactors = horizontalSamplingFactors.clone();
}
if (verticalSamplingFactors != null) {
newImgWrapper.verticalSamplingFactors = verticalSamplingFactors.clone();
}
if (streamMetadata != null) {
newImgWrapper.streamMetadata = NodeUtils.cloneNode(streamMetadata);
}
if (metadatas != null) {
newImgWrapper.metadatas = new Node[metadatas.length];
for (int i = 0; i < metadatas.length; i++) {
newImgWrapper.metadatas[i] = NodeUtils.cloneNode(metadatas[i]);
}
}
return newImgWrapper;
}
/**
* 这个参数只有图片格式是JPEG的时候才有意义,表示图片内容已经损坏
*
* @return the broken
*/
public boolean isBroken() {
return broken;
}
/**
* 这个参数只有图片格式是JPEG的时候才有意义,表示图片内容已经损坏
*
* @param broken the broken to set
*/
public void setBroken(boolean broken) {
this.broken = broken;
}
}