工具類:ImageUtil
package com.blogs.image;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class ImageUtil {
/** 圖片水印:支持旋轉、透明度、位置控制 */
public static void waterMarkImageByIcon(String iconPath, String srcImgPath,
String targerPath, Integer degree, Integer width, Integer height, float clarity) {
OutputStream os = null;
try {
Image srcImg = ImageIO.read(new File(srcImgPath));
BufferedImage buffImg = new BufferedImage(
srcImg.getWidth(null), srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffImg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null),
Image.SCALE_SMOOTH), 0, 0, null);
if (degree != null) {
g.rotate(Math.toRadians(degree),
(double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
}
ImageIcon imgIcon = new ImageIcon(iconPath);
Image img = imgIcon.getImage();
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, clarity));
g.drawImage(img, width, height, null);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
g.dispose();
os = new FileOutputStream(targerPath);
ImageIO.write(buffImg, "JPG", os);
System.out.println("添加水印圖片完成!");
} catch (Exception e) { e.printStackTrace(); }
finally { closeQuietly(os); }
}
/** 文字水印:支持字體、顏色、旋轉、透明度 */
public static void waterMarkByText(String logoText, String srcImgPath,
String targerPath, Integer degree, Integer width, Integer height, Float clarity) {
OutputStream os = null;
try {
Image srcImg = ImageIO.read(new File(srcImgPath));
BufferedImage buffImg = new BufferedImage(
srcImg.getWidth(null), srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffImg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null),
Image.SCALE_SMOOTH), 0, 0, null);
if (degree != null) {
g.rotate(Math.toRadians(degree),
(double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
}
g.setColor(Color.RED);
g.setFont(new Font("宋體", Font.BOLD, 30));
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, clarity));
g.drawString(logoText, width, height);
g.dispose();
os = new FileOutputStream(targerPath);
ImageIO.write(buffImg, "JPG", os);
System.out.println("添加水印文字完成!");
} catch (Exception e) { e.printStackTrace(); }
finally { closeQuietly(os); }
}
/** 等比縮放並居中白邊填充 */
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(); }
}
private static void closeQuietly(Closeable c) {
if (c != null) try { c.close(); } catch (IOException ignored) {}
}
}
參數說明
| 參數 | 含義 | 示例 |
| iconPath / logoText | 水印圖片路徑 / 水印文字內容 | "logo.png" / "版權所有" |
| srcImgPath | 源圖片路徑 | "photo.jpg" |
| targerPath | 輸出圖片路徑 | "photo_wm.jpg" |
| degree | 旋轉角度(度),null 為不旋轉 | 45 / -30 |
| width, height | 水印左上角座標(相對畫布左上角) | 100, 200 |
| clarity | 透明度 0.0f(全透明)~1.0f(不透明) | 0.3f |
關鍵技術點總結
- AlphaComposite.SRC_ATOP:只在源圖像非透明區域顯示水印,配合
clarity 控制疊加透明度。
- Graphics2D.rotate:以畫布中心為軸旋轉,旋轉後座標系改變,繪製座標需相應調整。
- Image.SCALE_SMOOTH:雙線性插值縮放,質量優於
SCALE_FAST、SCALE_REPLICATE。
- ImageIO.write:標準 API 輸出,替代內部
JPEGCodec,支持 PNG、JPEG、BMP、WBMP、GIF(讀)。
- zoomImage:目標尺寸固定,源圖等比縮放居中,空白區填充白色,適合生成固定尺寸縮略圖。