package com.idega.graphics.image.business.impl;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import org.imgscalr.Scalr;
import org.imgscalr.Scalr.Method;
import org.imgscalr.Scalr.Mode;
import com.idega.core.business.DefaultSpringBean;
import com.idega.graphics.image.business.ImageResizer;
import com.idega.idegaweb.IWMainApplication;
import com.idega.idegaweb.IWMainApplicationSettings;
import com.idega.util.ArrayUtil;
import com.idega.util.FileUtil;
import com.idega.util.IOUtil;
import com.idega.util.ListUtil;
import com.idega.util.StringUtil;
public class ImageResizerImpl extends DefaultSpringBean implements ImageResizer {
@Override
public InputStream getScaledImage(int newWidth, int newHeight, InputStream streamToImage, String imageType) throws IOException {
if (newWidth < 0 || newHeight < 0 || streamToImage == null || StringUtil.isEmpty(imageType)) {
getLogger().warning("Invalid parameters!");
return null;
}
return getStream(getScaledImage(newWidth, newHeight, -1, streamToImage, imageType, null));
}
@Override
public ByteArrayOutputStream getScaledImage(int newWidth, int newHeight, InputStream streamToImage, String imageType, ByteArrayOutputStream output) throws IOException {
byte[] bytes = getScaledImage(newWidth, newHeight, -1, streamToImage, imageType, null);
if (bytes == null || bytes.length <= 0) {
return null;
}
InputStream input = null;
try {
if (output == null) {
output = new ByteArrayOutputStream();
}
input = new ByteArrayInputStream(bytes);
FileUtil.streamToOutputStream(input, output);
return output;
} finally {
IOUtil.close(input);
}
}
@Override
public InputStream getScaledImage(int minSize, InputStream streamToImage, String imageType) throws IOException {
return getStream(getScaledImage(-1, -1, minSize, streamToImage, imageType, null));
}
@Override
public InputStream getScaledImageIfBigger(int newSize, InputStream streamToImage, String imageType) throws IOException {
return getStream(getScaledImage(-1, -1, newSize, streamToImage, imageType, newSize));
}
private InputStream getStream(byte[] bytes) {
if (bytes == null || bytes.length <= 0) {
return null;
}
return new ByteArrayInputStream(bytes);
}
private byte[] getScaledImage(
int newWidth,
int newHeight,
int minSize,
InputStream streamToImage,
String imageType,
Integer scaleIfBiggerThan
) throws IOException {
if (streamToImage == null) {
getLogger().warning("Stream to image is not provided!");
return null;
}
int originalWidth = -1, originalHeight = -1;
long start = System.currentTimeMillis();
ByteArrayOutputStream output = null;
try {
BufferedImage image = ImageIO.read(streamToImage);
originalHeight = image.getHeight();
boolean scale = true;
if (scaleIfBiggerThan != null && originalHeight <= scaleIfBiggerThan) {
scale = false;
}
BufferedImage scaled = null;
if (scale) {
if (newWidth < 0 && newHeight < 0 && minSize > 0) {
originalWidth = image.getWidth();
double ratio = minSize * 1.0 / originalWidth;
newHeight = Double.valueOf(originalHeight * ratio).intValue();
if (newHeight < minSize) {
ratio = minSize * 1.0 / originalHeight;
}
newHeight = Double.valueOf(originalHeight * ratio).intValue();
newWidth = Double.valueOf(originalWidth * ratio).intValue();
}
IWMainApplicationSettings settings = IWMainApplication.getDefaultIWMainApplication().getSettings();
List<BufferedImageOp> options = new ArrayList<BufferedImageOp>();
if (settings.getBoolean("graphics.resizer_antialias", Boolean.TRUE)) {
options.add(Scalr.OP_ANTIALIAS);
}
if (settings.getBoolean("graphics.resizer_brighter", Boolean.TRUE)) {
options.add(Scalr.OP_BRIGHTER);
}
Method method = Method.valueOf(settings.getProperty("graphics.resizer_method", Method.SPEED.name()));
Mode resizeMode = Mode.valueOf(settings.getProperty("graphics.resizer_mode", Mode.AUTOMATIC.name()));
if (ListUtil.isEmpty(options)) {
scaled = Scalr.resize(image, method, resizeMode, newWidth, newHeight);
} else {
scaled = Scalr.resize(image, method, resizeMode, newWidth, newHeight, ArrayUtil.convertListToArray(options));
}
} else {
scaled = image;
}
output = new ByteArrayOutputStream();
ImageIO.write(scaled, imageType, output);
return output.toByteArray();
} finally {
IOUtil.close(streamToImage);
IOUtil.close(output);
long duration = System.currentTimeMillis() - start;
if (duration > 300) {
getLogger().info("It took " + duration + " ms to scale image from " + originalWidth + "x" + originalHeight + " to " +
newWidth + "x" + newHeight);
}
}
}
}