Java给图片增加水印,根据图片大小自适应,右下角/斜角/平铺

您所在的位置:网站首页 水印换颜色 Java给图片增加水印,根据图片大小自适应,右下角/斜角/平铺

Java给图片增加水印,根据图片大小自适应,右下角/斜角/平铺

2024-07-01 07:55| 来源: 网络整理| 查看: 265

Hi,I’m Shendi 最近写自己的文件服务器,上传图片时需要自动增加水印,在这里记录一下

文章目录 效果展示读取图片从 byte[] 读取图片 获取画板绘制水印根据图片大小自适应水印大小右下角文字水印斜角水印平铺水印图片水印 输出图片

水印就是在图片上绘画,文字水印是最常见的,比如CSDN文章里图片右下角就会有文字水印

在 Java 中,给图片添加水印一般可以分为以下几步

读取图片获取/创建图片画板将水印内容绘制到图片中输出图片 效果展示

下面展示的是我所使用的水印效果

测试图片是百度拿的

原图 测试图片

加上水印后 加上水印后的图片 因我的要求不高,所以仅仅对角水印就可以了,可以根据自己需求绘制

读取图片

因为需要在图片上绘制,需要使用到 java.awt.image.BufferedImage 这个类

创建此类对象的方法有多种,这里只列出使用 ImageIO 将原图读取为 BufferedImage 的方式

// read 函数还可以传递输入流,例如直接使用FileInputStream -但需要自己关闭流 BufferedImage img = ImageIO.read(new File("文件地址")); 从 byte[] 读取图片 // 图片数据 byte[] imgData; ByteArrayInputStream bInput = new ByteArrayInputStream(imgData); BufferedImage img = ImageIO.read(bInput); 获取画板 Graphics g = img.getGraphics();

上面这种拿到的画板可以画线条圆圈文字等,但是不能旋转

需要旋转的话使用 Graphics2D

Graphics2D g = img.createGraphics(); 绘制水印

绘制文字的函数

// 参数一为需要绘制的文字,参数2,3为绘制的位置 img.drawString("文字", x, y);

经过测试,在坐标 0,0 绘制的文字显示的位置是在左上角,但文字是往上显示的,如下图所示 在这里插入图片描述 所以如果想让文字在最左上角显示的话,y需要加上文字的大小

// 设置文字大小,参数一为字体名称,二为样式,三为大小 g.setFont(new Font("黑体", Font.PLAIN, 20)); img.drawString("Shendi", x, 20);

效果如下 在这里插入图片描述

根据图片大小自适应水印大小

首先需要知道如何获取图片大小,拿到BufferedImage,可以通过以下函数获取

// width宽, height高 int width = img.getWidth(); int height = img.getHeight();

拿到宽高后,实现自适应就很简单了,按比例设置文字大小即可 例如

// 这里根据自己需求操作 int fontSize = (width+height) / 40; g.setFont(new Font("黑体", Font.PLAIN, fontSize)); 右下角文字水印

上面已经实现左上角水印了,而且将图片位置拿到了,于是右下角水印就非常简单了

因为在右下角,文字是往右显示的,所以需要得到文字显示占用的宽度,经过测试

单个汉字占用宽度=文字大小 单个字母数字符号占用=文字大小 / 2

中文转bytes占3字节,字母数字只占一字节 于是封装了以下函数

/** * 获取字符串占用的宽度 * * @author Shendi QQ * @param str 字符串 * @param fontSize 文字大小 * @return 字符串占用的宽度 */ public static int getStrWidth(String str, int fontSize) { char[] chars = str.toCharArray(); int fontSize2 = fontSize / 2; int width = 0; for (char c : chars) { int len = String.valueOf(c).getBytes().length; // 汉字为3,其余1 // 可能还有一些特殊字符占用2等等,统统计为汉字 if (len != 1) { width += fontSize; } else { width += fontSize2; } } return width; }

接下来将文字绘制到右下角就可以看到效果了

String str = "Shendi 砷碲"; g.setFont(new Font("黑体", Font.PLAIN, fontSize)); g.drawString(str, width - getStrWidth(str, fontSize), height);

在这里插入图片描述

可以给 x 往左移动一点,y往上移动一点,不要在最右下角 水印颜色一般都是透明的,设置透明度达到比较好的效果

String str = "Shendi 砷碲"; // 这里的 new Color四个参数为 rgba,值可以为 0-255, r红,g绿,b蓝,a透明度 g.setColor(new Color(0, 0, 0, 50)); g.setFont(new Font("黑体", Font.PLAIN, fontSize)); g.drawString(str, width - getStrWidth(str, fontSize) - 30, height - 30);

效果如下 在这里插入图片描述

换张图效果如下 在这里插入图片描述

完整代码如下

BufferedImage img = ImageIO.read(new File("图片位置")); int width = img.getWidth(); int height = img.getHeight(); int fontSize = (width+height) / 40; String str = "Shendi 砷碲"; Graphics2D g = img.createGraphics(); g.setColor(new Color(0, 0, 0, 50)); g.setFont(new Font("黑体", Font.PLAIN, fontSize)); g.drawString(str, width - getStrWidth(str, fontSize) - 30, height - 30); g.dispose(); ImageIO.write(img, "png", new File("水印图片保存地址")); 斜角水印

右下角水印只有一个,而且所在位置很容易被p图去掉

于是我使用多个水印,简单的排列的话可以横着,竖着,但是斜着是比较好的,所以我使用了这种,也是最开始的展示效果

绘制一定数量的水印,将图片宽高按比例分成 n 份,然后循环绘制水印

BufferedImage img = ImageIO.read(new File("图片地址")); int width = img.getWidth(); int height = img.getHeight(); // 绘制几个水印/分成几份 int num = 5; // 每一份x,y的大小 int splitX = width / num, splitY = height / num; // 每一份中间的位置 int centerX = splitX / 2, centerY = splitY / 2; int fontSize = (width+height) / 40; Graphics2D g = img.createGraphics(); g.setFont(new Font("黑体", Font.PLAIN, fontSize)); g.setColor(new Color(0, 0, 0, 30)); // 设置旋转角度,可以为0-1 g.rotate(0.2); for (int i = 1; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3