/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS,
* <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) 1999-2006 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <p>
*/
package org.olat.core.util;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import org.olat.core.util.vfs.VFSLeaf;
// FIXME:as:c google for deployment of servers with no X installed (fj)
// see also
// http://java.sun.com/j2se/1.5.0/docs/guide/awt/AWTChanges.html#headless
/**
* Helper class which scale an image and saved it as jpeg. Input format are
* the ones supported by standard java: gif, jpg, png.
*
* @author Alexander Schneider, srosse
*/
public class ImageHelper {
private static final String OUTPUT_FORMAT = "jpeg";
/**
* scales *.gif, *.jpg, *.png
*
* @param image the image to scale
* @param scaledImage the new scaled image
* @param maxSize the maximum size (height or width) of the new scaled image
* @return boolean
*/
public static boolean scaleImage(File image, File scaledImage, int maxSize) {
return scaleImage(image, scaledImage, maxSize, maxSize);
}
/**
* @param image the image to scale
* @param scaledImaged the new scaled image
* @param maxSize the maximum size (height or width) of the new scaled image
* @return
*/
public static boolean scaleImage(InputStream image, VFSLeaf scaledImage, int maxSize) {
try {
OutputStream bos = new BufferedOutputStream(scaledImage.getOutputStream(false));
boolean result = scaleImage(image, bos, maxSize, maxSize);
FileUtils.closeSafely(image);
FileUtils.closeSafely(bos);
return result;
} catch (Exception e) {
return false;
}
}
/**
* @param image the image to scale
* @param scaledImaged the new scaled image
* @param maxWidth the maximum width of the new scaled image
* @param maxheight the maximum height of the new scaled image
* @return
*/
public static boolean scaleImage(File image, File scaledImage, int maxWidth, int maxHeight) {
try {
BufferedImage imageSrc = ImageIO.read(image);
if (imageSrc == null) {
// happens with faulty Java implementation, e.g. on MacOSX Java 10, or
// unsupported image format
return false;
}
Size scaledSize = calcScaledSize(imageSrc, maxWidth, maxHeight);
return writeTo(scaleTo(imageSrc, scaledSize), scaledImage);
} catch (IOException e) {
return false;
}
}
/**
* @param image the image to scale
* @param scaledImaged the new scaled image
* @param maxWidth the maximum width of the new scaled image
* @param maxheight the maximum height of the new scaled image
* @return
*/
public static boolean scaleImage(InputStream image, OutputStream scaledImage, int maxWidth, int maxHeight) {
try {
BufferedImage imageSrc = ImageIO.read(image);
if (imageSrc == null) {
// happens with faulty Java implementation, e.g. on MacOSX Java 10, or
// unsupported image format
return false;
}
Size scaledSize = calcScaledSize(imageSrc, maxWidth, maxHeight);
return writeTo(scaleTo(imageSrc, scaledSize), scaledImage);
} catch (IOException e) {
return false;
}
}
/**
* Calculate the size of the new image. The method keep the ratio and doesn't
* scale up the image.
* @param image the image to scale
* @param maxWidth the maximum width of the new scaled image
* @param maxheight the maximum height of the new scaled image
* @return
*/
private static Size calcScaledSize(BufferedImage image, int maxWidth, int maxHeight) {
int width = image.getWidth();
int height = image.getHeight();
if(maxHeight > height && maxWidth > width) {
return new Size(width, height);
}
double thumbRatio = (double)maxWidth / (double)maxHeight;
double imageRatio = (double)width / (double)height;
if (thumbRatio < imageRatio) {
maxHeight = (int)(maxWidth / imageRatio);
}
else {
maxWidth = (int)(maxHeight * imageRatio);
}
return new Size(maxWidth, maxHeight);
}
/**
* Can change this to choose a better compression level as the default
* @param image
* @param scaledImage
* @return
*/
private static boolean writeTo(BufferedImage image, OutputStream scaledImage) {
try {
return ImageIO.write(image, OUTPUT_FORMAT, scaledImage);
} catch (IOException e) {
return false;
}
}
/**
* Can change this to choose a better compression level as the default
* @param image
* @param scaledImage
* @return
*/
private static boolean writeTo(BufferedImage image, File scaledImage) {
try {
return ImageIO.write(image, OUTPUT_FORMAT, scaledImage);
} catch (IOException e) {
return false;
}
}
private static BufferedImage scaleTo(BufferedImage image, Size scaledSize) {
Image img = image.getScaledInstance(scaledSize.getWidth(), scaledSize.getHeight(), Image.SCALE_SMOOTH);
return toBufferedImage(img, scaledSize.getWidth(), scaledSize.getHeight(), BufferedImage.TYPE_INT_RGB);
}
private static BufferedImage toBufferedImage(Image image, int w, int h, int type) {
BufferedImage result = new BufferedImage(w, h, type);
Graphics2D g = result.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return result;
}
public static final class Size {
private final int width;
private final int height;
public Size(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() {
if(width <= 0) {
return 1;
}
return width;
}
public int getHeight() {
if(height <= 0) {
return 1;
}
return height;
}
}
}