/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU
* General Public License Version 3 only ("GPL").
* You may not use this file except in compliance with the License.
* You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
* See the License for the specific language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*
*/
package org.jopendocument.util;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.swing.ImageIcon;
/**
* Tools for Image manipulation
*/
public class ImageUtils {
public static BufferedImage createSmallerImage(File f, int maxWidth, int maxHeight) throws IOException {
final ImageInfo info = new ImageInfo();
final BufferedInputStream ins = new BufferedInputStream(new FileInputStream(f));
info.setInput(ins);
if (!info.check())
throw new IllegalStateException("unable to parse the picture");
ins.close();
final int w = info.getWidth();
final int h = info.getHeight();
if (w <= maxWidth && h <= maxHeight) {
return null;
}
final Image img = new ImageIcon(f.getAbsolutePath()).getImage();
return createSmallerImage(img, maxWidth, maxHeight);
}
/**
* Transform the passed image so that it fits into a rectangle of <code>maxWidth</code> by
* <code>maxHeight</code>.
*
* @param orginalImage the image to transform.
* @param maxWidth the maximum width of the returned image.
* @param maxHeight the maximum height of the returned image.
* @return an image that fits or <code>null</code> if <code>original</code> already fits.
*/
public static BufferedImage createSmallerImage(Image orginalImage, int maxWidth, int maxHeight) {
final int w = orginalImage.getWidth(null);
final int h = orginalImage.getHeight(null);
if (w <= maxWidth && h <= maxHeight)
return null;
final int newWidth, newHeight;
final float imageRatio = w / (float) h;
final float finalRatio = maxWidth / maxHeight;
if (imageRatio > finalRatio) {
newWidth = maxWidth;
newHeight = (int) (newWidth / imageRatio);
} else {
newHeight = maxHeight;
newWidth = (int) (newHeight * imageRatio);
}
return createQualityResizedImage(orginalImage, newWidth, newHeight);
}
/**
* Create a resized Image with high quality rendering, specifying a ratio rather than pixels.
*
* @param orginalImage the original Image
* @param finalRatio the ratio that the returned image will have.
* @param applySoftFilter soft filter
* @param bgColor the background color
* @param fast algorithm to use for resampling.
* @return the resized image of the given ratio.
*/
public static BufferedImage createQualityResizedImage(Image orginalImage, float finalRatio, boolean applySoftFilter, Color bgColor, boolean fast) {
int w = orginalImage.getWidth(null);
int h = orginalImage.getHeight(null);
float imageRatio = w / (float) h;
final int newWidth, newHeight;
if (finalRatio > imageRatio) {
newHeight = h;
newWidth = (int) (newHeight * finalRatio);
} else {
newWidth = w;
newHeight = (int) (newWidth / finalRatio);
}
return createQualityResizedImage(orginalImage, newWidth, newHeight, false, true, bgColor, fast);
}
/**
* Create a resized Image with high quality rendering
*
* @param orginalImage the original Image
* @param width the desired width
* @param height the desired heights
* @param applySoftFilter soft filter
* @param keepRatio <code>true</code> to keep the ratio
* @param bgColor the background color
* @param fast algorithm to use for resampling.
* @return the resized image of the given size
*/
public static BufferedImage createQualityResizedImage(Image orginalImage, int width, int height, boolean applySoftFilter, boolean keepRatio, Color bgColor, boolean fast) {
if (orginalImage == null) {
throw new IllegalArgumentException("null argument");
}
final BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bufferedImage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
int quality = Image.SCALE_SMOOTH;
if (fast) {
quality = Image.SCALE_FAST;
}
if (!keepRatio) {
Image resizedImage = orginalImage.getScaledInstance(width, height, quality);
// This code ensures that all the pixels in the image are loaded:
// NE PAS VIRER, deja trop de temps perdu a debugger ca!
Image temp = new ImageIcon(resizedImage).getImage();
g2.drawImage(temp, 0, 0, null);
} else {
// Clear background and paint the image.
g2.setColor(bgColor);
g2.fillRect(0, 0, width, height);
float W = width;
float H = height;
float w = orginalImage.getWidth(null);
float h = orginalImage.getHeight(null);
float imageRatio = w / h;
float finalRatio = W / H;
int newH, newW;
if (finalRatio > imageRatio) {
newW = Math.round(H * imageRatio);
newH = Math.round(H);
Image resizedImage = orginalImage.getScaledInstance(newW, newH, quality);
// This code ensures that all the pixels in the image are loaded:
// NE PAS VIRER, deja trop de temps perdu a debugger ca!
Image temp = new ImageIcon(resizedImage).getImage();
g2.drawImage(temp, (int) ((W - newW) / 2), 0, null);
} else {
newW = Math.round(W);
newH = Math.round(W / imageRatio);
Image resizedImage = orginalImage.getScaledInstance(newW, newH, quality);
// This code ensures that all the pixels in the image are loaded:
// NE PAS VIRER, deja trop de temps perdu a debugger ca!
Image temp = new ImageIcon(resizedImage).getImage();
g2.drawImage(temp, 0, (int) ((H - newH) / 2), null);
}
}
g2.dispose();
if (applySoftFilter) {
return getSoftFilteredImage(bufferedImage);
}
return bufferedImage;
}
public static BufferedImage createQualityResizedImage(Image orginalImage, int width, int height) {
return createQualityResizedImage(orginalImage, width, height, false, false, Color.WHITE, false);
}
public static BufferedImage createQualityResizedImage(Image orginalImage, int width, int height, boolean keepRatio) {
return createQualityResizedImage(orginalImage, width, height, false, keepRatio, Color.WHITE, false);
}
/**
* Create an soft filtered Image
*
* @param bufferedImage the orignial BufferedImage
* @return the soft filtered Image
*/
public static BufferedImage getSoftFilteredImage(BufferedImage bufferedImage) {
// soften
float softenFactor = 0.01f;
float[] softenArray = { 0, softenFactor, 0, softenFactor, 1 - (softenFactor * 3), softenFactor, 0, softenFactor, 0 };
Kernel kernel = new Kernel(3, 3, softenArray);
ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
bufferedImage = cOp.filter(bufferedImage, null);
return bufferedImage;
}
}