图片添加水印
需求是需要添加多个斜的水印,如果只是添加单个水印可以参考这个:传送门
直接上代码:
private static void waterMarkAdd(String sourceFile,String targetFile,String watermarkText)
throws IOException {
File srcImgFile = new File(sourceFile);
Image srcImg = ImageIO.read(srcImgFile);
int srcImgWidth = srcImg.getWidth(null);
int srcImgHeight = srcImg.getHeight(null);
//以图片宽高中短的一边为基准长度,控制水印的大小
int baseLength = (srcImgHeight + srcImgWidth) / 2;
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
//创建画笔
Graphics2D g = bufImg.createGraphics();
//srcImg 为上面获取到的原始图片的图片对象
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
//设置字体大小,大小根据图片尺寸变化,最小为30+文字长度
int fontSize = Math.max(baseLength / 20, 30 + watermarkText.length());
int textLength = g.getFontMetrics(g.getFont()).charsWidth(watermarkText.toCharArray(), 0, watermarkText.length());
//自适应文字大小
fontSize = (int) (fontSize - textLength * 0.2);
int fontLength = fontSize * (watermarkText.length() + 2);
//水印图片的宽
int watermarkImageWidth = (int) (fontLength * 0.7);
//水印图片的高
int watermarkImageHeight = fontLength / 2;
BufferedImage watermarkImage = new BufferedImage(watermarkImageWidth, watermarkImageHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D rotatedG2d = watermarkImage.createGraphics();
//设置背景为透明
watermarkImage = rotatedG2d.getDeviceConfiguration().createCompatibleImage(watermarkImageWidth, watermarkImageHeight, Transparency.TRANSLUCENT);
rotatedG2d.dispose();
//开始绘制水印文字
rotatedG2d = watermarkImage.createGraphics();
rotatedG2d.setFont(new Font("微软雅黑", Font.PLAIN, fontSize));
//文字自适应图片颜色
rotatedG2d.setColor(getMarkColor(bufImg, srcImgWidth, srcImgHeight));
double halfWidth = watermarkImageWidth / 2.0;
//水印文字逆时针旋转30°
rotatedG2d.rotate(Math.toRadians(-30), halfWidth, watermarkImageHeight / 2.0);
rotatedG2d.drawString(watermarkText, (int) (fontSize * 0.1), (int) (watermarkImageHeight / 1.75));
rotatedG2d.dispose();
//第一个水印的起始位置
int startX = 0;
int startY = (int) (-halfWidth);
//循环添加水印
for (int posX = startX; posX <= srcImgWidth; posX += watermarkImageWidth) {
for (int posY = startY; posY <= srcImgHeight; posY += watermarkImageHeight) {
//将绘制的水印文字图片画到原图片
g.drawImage(watermarkImage, posX, posY, null);
}
}
g.dispose();
// 输出图片
FileOutputStream outImgStream = new FileOutputStream(targetFile);
//这里转出的格式要与原来的相同,不然图片文件会变得异常大
String fileExtName = sourceFile.substring(souceFile.lastIndexOf(".") + 1);
ImageIO.write(bufImg, fileExtName, outImgStream);
System.out.println("添加水印完成");
outImgStream.flush();
outImgStream.close();
}
获取水印文字颜色方法
public static Color getMarkColor(BufferedImage bi, int w, int h) {
long sumR = 0;
long sumG = 0;
long sumB = 0;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
Color pixel = new Color(bi.getRGB(x, y));
sumR += pixel.getRed();
sumG += pixel.getGreen();
sumB += pixel.getBlue();
}
}
int num = w * h;
int markColor = (int) (sumR / num + sumG / num + sumB / num) / 3;
int halfRgb = 128;
if (markColor < halfRgb) {
markColor = markColor - 50 < 0 ? markColor + 50 : markColor - 50;
} else {
markColor = markColor + 50 > 255 ? markColor - 50 : markColor + 50;
}
return new Color(markColor, markColor, markColor, 100);
}
写一个main方法测试一下:
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
waterMarkAdd("D:/aaa.png","D:/watermark/aaa.png","我是水印");
System.out.println(System.currentTimeMillis()-start);
}
效果展示:
图片长宽1130 x 676,大小250kb,本机i5十一代笔记本处理器,耗时如下:
大概一秒左右
这个文字大小会自适应图片大小,然后水印颜色也会自适应图片颜色,不会出现刚好图片颜色跟水印一致而看不出水印的问题