package org.jboss.fresh.shell.commands.util;
import org.jboss.fresh.io.BufferInputStream;
import org.jboss.fresh.io.BufferObjectReader;
import org.jboss.fresh.io.BufferObjectWriter;
import org.jboss.fresh.io.BufferOutputStream;
import org.jboss.fresh.io.BufferWriter;
import org.jboss.fresh.shell.AbstractExecutable;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.PrintWriter;
public class ImgResizeExe extends AbstractExecutable {
private static transient org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(ImgResizeExe.class);
public static final String OBJ_TYPE = "obj";
public static final String IMG_TYPE = "img";
public void throwException(String msg) throws Exception {
if (canThrowEx()) {
throw new RuntimeException(msg);
} else {
PrintWriter out = new PrintWriter(new BufferWriter(getStdOut()));
out.println(msg);
out.close();
log.debug("done");
return;
}
}
public void process(String exepath, String[] params) throws Exception {
log.debug("entered");
if ((params.length == 0) || helpRequested()) {
printUsage();
return;
}
long maxWidth = -1;
long maxHeight = -1;
long height = -1;
long width = -1;
String inType = IMG_TYPE;
String outType = null;
String swidth = null, sheight = null, smaxWidth = null, smaxHeight = null;
java.io.PrintWriter out = new PrintWriter(new BufferedWriter(new BufferWriter(getStdOut())));
for (int i = 0; i < params.length; i++) {
String val = params[i];
if (val.equals("-width")) {
if (params.length >= i) {
swidth = params[++i];
try {
width = Integer.parseInt(swidth);
} catch (Exception e) {
throwException("Invalid width.");
return;
}
}
} else if (val.equals("-height")) {
if (params.length >= i) {
sheight = params[++i];
try {
height = Integer.parseInt(sheight);
} catch (Exception e) {
throwException("Invalid height.");
return;
}
}
} else if (val.equals("-maxHeight")) {
if (params.length >= i) {
smaxHeight = params[++i];
try {
maxHeight = Integer.parseInt(smaxHeight);
} catch (Exception e) {
throwException("Invalid maxHeight.");
return;
}
}
} else if (val.equals("-maxWidth")) {
if (params.length >= i) {
smaxWidth = params[++i];
try {
maxWidth = Integer.parseInt(smaxWidth);
} catch (Exception e) {
throwException("Invalid maxWidth.");
return;
}
}
} else if (val.equals("-in")) {
if (params.length >= i) {
inType = params[++i];
if (!inType.equals(OBJ_TYPE) && !inType.equals(IMG_TYPE)) {
throwException("Invalid in type");
return;
}
}
} else if (val.equals("-out")) {
if (params.length >= i) {
outType = params[++i];
if (!outType.equals(OBJ_TYPE) && !outType.equals(IMG_TYPE)) {
throwException("Invalid out type");
return;
}
}
}
}
if (outType == null) {
outType = inType;
}
try {
String param;
InputStream ins = new BufferInputStream(getStdIn());
BufferedImage image = null;
boolean useCache = false;
// Determine the scale.
double scale;
double scaleX;
double scaleY;
//log.debug("width: " + width);
//log.debug("height: " + height);
//log.debug("maxWidth: " + maxWidth);
//log.debug("maxHeight: " + maxHeight);
// if ((width == -1) && (height == -1)) {
// width = maxWidth;
// height = maxHeight;
// }
// READ IMAGE
if (inType.equals(IMG_TYPE)) {
image = ImageIO.read(ins);
if (image == null) {
throwException("No image retrieved from the pipeline!");
return;
}
} else { //OBJ_TYPE
BufferObjectReader oin = new BufferObjectReader(getStdIn());
if (oin.hasNext()) {
image = (BufferedImage) oin.next();
}
oin.close();
if (image == null) {
throwException("No image object retrieved from the pipeline!");
return;
}
}
if (!useCache) {
int imgW = image.getWidth(null);
int imgH = image.getHeight(null);
//log.debug("image width: " + imgW);
//log.debug("image height: " + imgH);
float iRatio = imgW / (float) imgH;
// if request for fullsize image truncate width and height to maximums
if ((width == -1) && (height == -1)) {
if (maxWidth != -1 && imgW > maxWidth) width = maxWidth;
if (maxHeight != -1 && imgH > maxHeight) height = maxHeight;
}
//log.debug("width: " + width);
//log.debug("height: " + height);
// if max requested height is known calculate aspect ratio width.
// If it is greater than the width specified set width with it.
if (height != -1) {
int altwidth = (int) (height * iRatio);
//log.debug("altwidth: " + altwidth);
//if(altwidth>width && width!=-1) width=altwidth;
if (altwidth > width) width = altwidth;
}
// if max requested width is known calculate aspect ratio height.
// If it is greater than the height set the height width it.
if (width != -1) {
int altheight = (int) (width / iRatio);
//log.debug("altheight: " + altheight);
//if(altheight>height && height!=-1) height=altheight;
if (altheight > height) height = altheight;
}
//log.debug("After ratio check: ");
//log.debug("width: " + width);
//log.debug("height: " + height);
if ((width > maxWidth) && (maxWidth != -1)) {
width = maxWidth;
//log.debug("Truncated width to maxWidth: " + width);
height = (int) (width / iRatio);
//log.debug("Adapted height to : " + height);
}
if (width > imgW) {
width = imgW;
//log.debug("Truncated width to img Width: " + width);
height = (int) (width / iRatio);
//log.debug("Adapted height to : " + height);
}
if (((height == -1) || (height > maxHeight)) && (maxHeight != -1)) {
height = maxHeight;
//log.debug("Truncated height to maxHeight: " + height);
width = (int) (height * iRatio);
//log.debug("Adapted width to : " + width);
}
if (height > imgH) {
height = imgH;
//log.debug("Truncated height to img Height: " + height);
width = (int) (height * iRatio);
//log.debug("Adapted width to : " + width);
}
//log.debug("width: " + width);
//log.debug("height: " + height);
if ((imgW > imgH) || (height == -1)) {
scale = (double) width / (double) imgW;
} else {
scale = (double) height / (double) imgH;
}
int scaledW = (int) (scale * imgW);
int scaledH = (int) (scale * imgH);
// Shit. No cache. Do some resizing.
/*
* response.setHeader("Cache-Control", "post-check=900,pre-check=3600");
* response.addHeader("Expires", dt(timeout) );
* response.addHeader("Last-Modified", dt(0) );
* response.setHeader("Date", dt(0) );
*/
// fetch the image
// Create an image buffer in which to paint on.
BufferedImage newImage = new BufferedImage(scaledW, scaledH, BufferedImage.TYPE_INT_RGB);
// Set the scale.
AffineTransform tx = new AffineTransform();
// If the image is smaller than the desired image size,
// don't bother scaling.
if (scale < 1.0d) {
tx.scale(scale, scale);
}
// Paint image.
Graphics2D g2d = newImage.createGraphics();
//RenderingHints rh = new RenderingHints(java.awt.RenderingHints.KEY_ANTIALIASING,java.awt.RenderingHints.VALUE_ANTIALIAS_ON);
RenderingHints rh = new RenderingHints(java.awt.RenderingHints.KEY_INTERPOLATION, java.awt.RenderingHints.VALUE_INTERPOLATION_BICUBIC);
//rh.add(java.awt.RenderingHints.KEY_ANTIALIASING,java.awt.RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHints(rh);
g2d.drawImage(image, tx, null);
g2d.dispose();
// WRITE IMAGE
if (outType.equals(IMG_TYPE)) {
BufferOutputStream bos = new BufferOutputStream(getStdOut());
ImageIO.write(newImage, "jpg", bos);
bos.close();
/*
OutputStream os = new BufferedOutputStream(new BufferOutputStream(getStdOut()));
JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(os);
jpegEncoder.encode(newImage);
os.close();
*/
} else { // OBJ_TYPE
BufferObjectWriter oout = new BufferObjectWriter(getStdOut());
oout.writeObject(newImage);
oout.close();
}
return;
}
ins.close();
} catch (Exception e) {
// If an Exception occurs, return the error to the client.
if (canThrowEx()) {
throw new RuntimeException("Invalid maxHeight.");
} else {
out.println("Invalid maxHeight.");
return;
}
}
// Close the PrintWriter.
out.close();
log.debug("done");
}
private void printUsage() {
PrintWriter pout = new PrintWriter(new BufferedWriter(new BufferWriter(getStdOut())));
pout.println("Usage:\n");
pout.println(" imgresize [--help] [-ex] [-width <width>] [-height <height>] [-maxWidth <maxWidth>] [-maxHeight <maxHeight>] [-in <inType>] [-out <outType>]");
pout.println(" inType, outType : type of input and output [img | obj], img-binary image(default), obj-BufferedImage object");
pout.println(" --help : this help");
pout.flush();
}
}