核心類:CompressPicDemo
package com.img;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class CompressPicDemo {
private File file;
private String inputDir, outputDir, inputFileName, outputFileName;
private int outputWidth = 100, outputHeight = 100;
private boolean proportion = true; // 默認等比縮放
// 省略 getter/setter ...
public long getPicSize(String path) {
file = new File(path);
return file.length();
}
public String compressPic() {
try {
file = new File(inputDir + inputFileName);
if (!file.exists()) return "";
Image img = ImageIO.read(file);
if (img.getWidth(null) == -1) return "no";
int newWidth, newHeight;
if (proportion) {
double rate1 = (double) img.getWidth(null) / outputWidth + 0.1;
double rate2 = (double) img.getHeight(null) / outputHeight + 0.1;
double rate = Math.max(rate1, rate2);
newWidth = (int) (img.getWidth(null) / rate);
newHeight = (int) (img.getHeight(null) / rate);
} else {
newWidth = outputWidth;
newHeight = outputHeight;
}
BufferedImage tag = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
tag.getGraphics().drawImage(
img.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), 0, 0, null);
FileOutputStream out = new FileOutputStream(outputDir + outputFileName);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(tag);
out.close();
return "ok";
} catch (IOException ex) {
ex.printStackTrace();
return "error";
}
}
// 重載方法支持參數直傳
public String compressPic(String inputDir, String outputDir, String inputFileName,
String outputFileName, int width, int height, boolean gp) {
this.inputDir = inputDir; this.outputDir = outputDir;
this.inputFileName = inputFileName; this.outputFileName = outputFileName;
this.outputWidth = width; this.outputHeight = height; this.proportion = gp;
return compressPic();
}
public static void main(String[] arg) {
CompressPicDemo demo = new CompressPicDemo();
System.out.println("原圖大小:" + demo.getPicSize("e:\\1.jpg")/1024 + "KB");
demo.compressPic("e:\\", "e:\\test\\", "1.jpg", "r1.jpg", 120, 120, false);
}
}
關鍵技術點
- 等比縮放算法:分別計算寬高縮放比,取較大者作為統一比率,保證圖片完整顯示在目標矩形內。
- Image.SCALE_SMOOTH:優先質量的縮放算法,生成圖片平滑度高,速度稍慢。
- BufferedImage.TYPE_INT_RGB:24位 RGB 模型,適合 JPEG 編碼;若需透明通道用
TYPE_INT_ARGB。
- JPEGImageEncoder:Sun 內部類,生產環境建議替換為
ImageIO.write(tag, "jpg", out) 並配合 ImageWriteParam 控制質量。
補充:圖片縮放帶白邊填充工具方法
public static void zoomImage(String srcPath, String destPath, int destHeight, int destWidth) {
try {
BufferedImage src = ImageIO.read(new File(srcPath));
int imgWidth = destWidth, imgHeight = destHeight;
if (src.getHeight() >= src.getWidth()) {
imgWidth = (int) Math.round((destHeight * 1.0 / src.getHeight()) * src.getWidth());
} else {
imgHeight = (int) Math.round((destWidth * 1.0 / src.getWidth()) * src.getHeight());
}
BufferedImage dest = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = dest.createGraphics();
g.setBackground(Color.WHITE);
g.clearRect(0, 0, destWidth, destHeight);
g.drawImage(src.getScaledInstance(imgWidth, imgHeight, Image.SCALE_SMOOTH),
(destWidth - imgWidth)/2, (destHeight - imgHeight)/2, null);
g.dispose();
ImageIO.write(dest, "JPEG", new File(destPath));
} catch (IOException e) { e.printStackTrace(); }
}