package com.itstherules.image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.media.jai.InterpolationBicubic2;
import javax.media.jai.InterpolationNearest;
import javax.media.jai.JAI;
import javax.media.jai.OpImage;
import javax.media.jai.PlanarImage;
import javax.media.jai.RenderedOp;
import javax.media.jai.operator.CropDescriptor;
import javax.media.jai.operator.TransposeDescriptor;
import javax.media.jai.operator.TransposeType;
import com.sun.media.jai.codec.SeekableStream;
public class JAIImage implements IImage {
private static final RenderingHints RENDERING_HINTS = new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
private PlanarImage image;
private String fileName;
public JAIImage(String fileName) throws FileNotFoundException {
this.fileName = fileName;
InputStream inputStream = new FileInputStream(this.fileName);
SeekableStream seekableStream = SeekableStream.wrapInputStream(inputStream, true);
RenderedOp image = JAI.create("stream", seekableStream);
((OpImage) image.getRendering()).setTileCache(null);
this.image = image;
}
public void crop(Point top, Point bottom) {
if (top == null || bottom == null) { return; }
float x = top.x;
float y = top.y;
float width = bottom.x - top.x;
float height = bottom.y - top.y;
this.image = CropDescriptor.create(image, new Float(x), new Float(y), new Float(width), new Float(height), RENDERING_HINTS);
}
public void scale(int width, int height, boolean highQuality, boolean maintainAspect) {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
if (width == -1) {
width = imageWidth;
maintainAspect = true;
}
if (height == -1) {
height = imageHeight;
maintainAspect = true;
}
float xScale, yScale;
xScale = (float) width / (float) imageWidth;
yScale = (float) height / (float) imageHeight;
if (maintainAspect) {
float scale = Math.min(xScale, yScale);
xScale = scale;
yScale = scale;
}
ParameterBlock parameterBlock = new ParameterBlock();
parameterBlock.addSource(image);
parameterBlock.add(yScale);
parameterBlock.add(yScale);
parameterBlock.add(0.0F);
parameterBlock.add(0.0F);
if (!highQuality) {
parameterBlock.add(new InterpolationNearest());
} else {
parameterBlock.add(new InterpolationBicubic2(8));
}
this.image = JAI.create("scale", parameterBlock, RENDERING_HINTS);
}
public void rotate(int rotateAmount) {
if (rotateAmount == 0) {
return;
}
TransposeType type = TransposeDescriptor.ROTATE_90;
switch (rotateAmount) {
case 90:
type = TransposeDescriptor.ROTATE_90;
break;
case 180:
type = TransposeDescriptor.ROTATE_180;
break;
case -90:
type = TransposeDescriptor.ROTATE_270;
break;
}
this.image = TransposeDescriptor.create(image, type, RENDERING_HINTS);
}
public int getWidth() {
return image.getWidth();
}
public int getHeight() {
return image.getHeight();
}
public void save() throws IOException {
saveAs(fileName);
}
public void saveAs(String fileName) throws IOException {
ImageIO.write(image, new FileUtils().suffix(fileName), new File(fileName));
}
public void streamTo(OutputStream outputStream) throws IOException {
ImageIO.write(image, new FileUtils().suffix(fileName), outputStream);
}
}