之前和 [yoshi] 討論圖片放大和縮小的程式該如何實作,隨手就寫了一個類別出來。這個類別可以用等比例的方法來縮放,也可以自己重新 resize,然後存檔。用在網頁或是應用程式中還算方便,稍為修改一下就可以擴充應用。不過只能處理 JPEG 和 PNG 兩個格式,因為 GIF 的 LZW 壓縮法有版權專利的問題。如果想處理 GIF 的話,可以試試 Acme 的編碼程式,它是用 LZ 壓縮法,所以沒有版權上的顧慮。
提供一個簡單的類別來更改圖片大小。
/**
* Image utility.
*
* @author Joseph Kuo
* @since
*/
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageUtils {
public static final String JPEG_SUFFIX_1 = "jpg";
public static final String JPEG_SUFFIX_2 = "jpeg";
public static final String PNG_SUFFIX = "png";
public static final String GIF_SUFFIX = "gif";
public static final String[] IMAGE_SUFFIXES = {
PNG_SUFFIX, GIF_SUFFIX, JPEG_SUFFIX_1, JPEG_SUFFIX_2
};
// Check if the name of the given file has image format suffix.
public static boolean isImage(File file) {
return file != null && isImageFilename(file.getName());
}
// Check if the given name has image format suffix.
public static boolean isImageFilename(String filename) {
if (filename == null || filename.length() < 1) {
return false;
}
// Check if it has "."
int index = filename.lastIndexOf(".");
if (-1 == index) {
return false;
}
// Check the extension.
String filenameExt = filename.substring(index + 1);
for (String ext : IMAGE_SUFFIXES) {
if (ext.equalsIgnoreCase(filenameExt)) {
return true;
}
}
return false;
}
// width: target width, height: target height.
public static boolean scaleImage(File source, File target, int width, int height) {
// Check if source is an image and readable.
if (!isImage(source)) {
return false;
}
BufferedImage bImage = null;
try {
bImage = ImageIO.read(source);
} catch (IOException ex) {
}
if (null == bImage) {
return false;
}
// Set right width and height.
int sWidth = bImage.getWidth();
int sHeight = bImage.getHeight();
if (width <= 0 && height <= 0) {
width = sWidth;
height = sHeight;
} else if (width <= 0) {
width = (int) ((double) sWidth * height / sHeight);
} else if (height <= 0) {
height = (int) ((double) sHeight * width / sWidth);
}
// Prepare the target image environment.
BufferedImage bImage2 = null;
if (bImage.getType() != BufferedImage.TYPE_CUSTOM) {
bImage2 = new BufferedImage(width, height, bImage.getType());
Graphics2D g2d = (Graphics2D) bImage2.getGraphics();
g2d.scale((double) width / sWidth, (double) height / sHeight);
g2d.drawImage(bImage, 0, 0, null);
g2d.dispose();
} else {
ColorModel cm = bImage.getColorModel();
WritableRaster raster = cm.createCompatibleWritableRaster(width, height);
boolean alphaPremultiplied = cm.isAlphaPremultiplied();
bImage2 = new BufferedImage(cm, raster, alphaPremultiplied, null);
}
try {
// Get image format.
String formatName = source.getName().substring(source.getName().indexOf("."));
// We can not save a file as "gif", so we save it as "png".
if (GIF_SUFFIX.equalsIgnoreCase(formatName)) {
formatName = PNG_SUFFIX;
}
// And we also choose the right JPEG format "jpeg" instand of "jpg"
if (!PNG_SUFFIX.equalsIgnoreCase(formatName)) {
formatName = JPEG_SUFFIX_2;
}
ImageIO.write(bImage2, formatName, target);
} catch (IOException ex) {
return false;
}
return true;
}
}
Hi
I’ve used your code and it seems great. Below is my suggestion.
Change g2d.drawImage(bimage, 0, 0, new JFrame()); to g2d.drawImage(bimage, 0, 0, null); is better, otherwise, it can only run in graphic mode but not text mode.
JFrame() will throw
HeadlessException – if GraphicsEnvironment.isHeadless() returns true.
GraphicsEnvironment.isHeadless() returns
true if this environment cannot support a display, keyboard, and mouse; false otherwise
Thanks for your suggestion.
I wrote this test Class file in 2003 for a Java program plan. The code here is the first version, and I write a new version which uses a null object instead of JFrame() in 2004. So it now could works under the environment in text mode and not waste the momery for a needless JFrame object that is not really used.
Thanks again, for your using.:)