用java实现给图片增加图片水印或者文字水印(也支持视频图像帧添加水印)

2018-06-19 16:38:06

javaCV图像处理系列:

javaCV图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体、位置、大小、粗度、翻转、平滑等操作

javaCV图像处理之2:实时视频添加图片水印,实现不同大小图片叠加,图像透明度控制

  

前言:

这是个很常用的操作,一般我们的网站在用户上传图片时都会给图片添加一个水印以防止其他站点盗图的行为

实现功能:①给图片增加文字水印②给图片增加图片水印

一、核心功能实现:

1、添加文字水印

[java] view plain copy

  1. // 加文字水印  

  2.     public void mark(BufferedImage bufImg, Image img, String text, Font font, Color color, int x, int y) {  

  3.         Graphics2D g = bufImg.createGraphics();  

  4.         g.drawImage(img, 00, bufImg.getWidth(), bufImg.getHeight(), null);  

  5.         g.setColor(color);  

  6.         g.setFont(font);  

  7.         g.drawString(text, x, y);  

  8.         g.dispose();  

  9.     }  

2、添加图片水印


[java] view plain copy

  1. // 加图片水印  

  2.     public void mark(BufferedImage bufImg, Image img, Image markImg, int width, int height, int x, int y) {  

  3.         Graphics2D g = bufImg.createGraphics();  

  4.         g.drawImage(img, 00, bufImg.getWidth(), bufImg.getHeight(), null);  

  5.         g.drawImage(markImg, x, y, width, height, null);  

  6.         g.dispose();  

  7.     }  



以上两个方法实现了最核心的功能:给图片添加水印。

补充:

为什么要这么写?

考虑到该方法不仅可以用于给图片文件增加水印,而且还可以给视频的每一帧图像也添加,所以为了方便不同场合重复使用,去除了不必要的依赖关系。

有了核心的两个方法就我们可以给图片文件增加水印了

二、功能性实现

1、给图片增加文字水印

[java] view plain copy

  1. /** 

  2.      * 给图片增加文字水印 

  3.      *  

  4.      * @param imgPath 

  5.      *            -要添加水印的图片路径 

  6.      * @param outImgPath 

  7.      *            -输出路径 

  8.      * @param text-文字 

  9.      * @param font 

  10.      *            -字体 

  11.      * @param color 

  12.      *            -颜色 

  13.      * @param x 

  14.      *            -文字位于当前图片的横坐标 

  15.      * @param y 

  16.      *            -文字位于当前图片的竖坐标 

  17.      */  

  18.     public void mark(String imgPath, String outImgPath, String text, Font font, Color color, int x, int y) {  

  19.         try {  

  20.             // 读取原图片信息  

  21.             File imgFile = null;  

  22.             Image img = null;  

  23.             if (imgPath != null) {  

  24.                 imgFile = new File(imgPath);  

  25.             }  

  26.             if (imgFile != null && imgFile.exists() && imgFile.isFile() && imgFile.canRead()) {  

  27.                 img = ImageIO.read(imgFile);  

  28.             }  

  29.             int imgWidth = img.getWidth(null);  

  30.             int imgHeight = img.getHeight(null);  

  31.             // 加水印  

  32.             BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);  

  33.             mark(bufImg, img, text, font, color, x, y);  

  34.             // 输出图片  

  35.             FileOutputStream outImgStream = new FileOutputStream(outImgPath);  

  36.             ImageIO.write(bufImg, "jpg", outImgStream);  

  37.             outImgStream.flush();  

  38.             outImgStream.close();  

  39.         } catch (Exception e) {  

  40.             e.printStackTrace();  

  41.         }  

  42.     }  




2、给图片增加图片水印

[java] view plain copy

  1. /** 

  2.      * 给图片增加图片水印 

  3.      *  

  4.      * @param inputImg 

  5.      *            -源图片,要添加水印的图片 

  6.      * @param markImg 

  7.      *            - 水印图片 

  8.      * @param outputImg 

  9.      *            -输出图片(可以是源图片) 

  10.      * @param width 

  11.      *            - 水印图片宽度 

  12.      * @param height 

  13.      *            -水印图片高度 

  14.      * @param x 

  15.      *            -横坐标,相对于源图片 

  16.      * @param y 

  17.      *            -纵坐标,同上 

  18.      */  

  19.     public void mark(String inputImg, String markImg, String outputImg, int width, int height, int x, int y) {  

  20.         // 读取原图片信息  

  21.         File inputImgFile = null;  

  22.         File markImgFile = null;  

  23.         Image img = null;  

  24.         Image mark = null;  

  25.         try {  

  26.             if (inputImg != null && markImg != null) {  

  27.                 inputImgFile = new File(inputImg);  

  28.                 markImgFile = new File(markImg);  

  29.             }  

  30.             if (inputImgFile != null && inputImgFile.exists() && inputImgFile.isFile() && inputImgFile.canRead()) {  

  31.   

  32.                 img = ImageIO.read(inputImgFile);  

  33.   

  34.             }  

  35.             if (markImgFile != null && markImgFile.exists() && markImgFile.isFile() && markImgFile.canRead()) {  

  36.   

  37.                 mark = ImageIO.read(markImgFile);  

  38.   

  39.             }  

  40.             int imgWidth = img.getWidth(null);  

  41.             int imgHeight = img.getHeight(null);  

  42.             BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);  

  43.             mark(bufImg, img, mark, width, height, x, y);  

  44.             FileOutputStream outImgStream = new FileOutputStream(outputImg);  

  45.             ImageIO.write(bufImg, "jpg", outImgStream);  

  46.             outImgStream.flush();  

  47.             outImgStream.close();  

  48.         } catch (IOException e) {  

  49.             e.printStackTrace();  

  50.         }  

  51.     }  


3、测试一下效果


文字水印的字体和颜色需要自行定义,这里我们使用宋体,14号字体,颜色选择橙色 - -!,坐标是x轴0,y轴等于字体的大小,也就是图片的左上角。

[java] view plain copy

  1. public static void main(String[] args) {  

  2.         Font font = new Font("宋体", Font.PLAIN, 14);  

  3.         // 原图位置, 输出图片位置, 水印文字颜色, 水印文字  

  4.         // new MarkText4J().mark("eguidMarkText2.jpg", "eguidMarkText2.jpg", "水印效果测试", font, Color.ORANGE, 0, 14);  

  5.         // 增加图片水印  

  6.         new MarkText4J().mark("eguidMarkText2.jpg""eguid.jpg""eguidMarkText3.jpg"4020014);  

  7.     }  

简直棒极了,至此我们可以随意的给图片任意位置添加任意文字或者图片水印了。

最后,额。。。导出的图片比原本图片还小是什么鬼?欢迎加入讨论群一起讨论:371249677。- -!

  • 2020-03-18 21:30:57

    基于OpenLayers实现地理围栏 谷歌百度高德地图都可以

    前言.因为项目有点特殊,需要接入谷歌地图实现地理围栏,因为谷歌地图的地理围栏接口相关接口并不完善,于是就换了一个思路,利用OpenLayers来实现地理围栏 openlayers 中文地址 http://weilin.me/ol3-primer/ch02/index.html 作者:zcty0701 链接:https://www.jianshu.com/p/60e88ee1e843 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 2020-03-19 17:12:40

    百度地图放大覆盖物消失

    产生问题的原因是因为我们用的普通的点数组生成的多边形,我们应该用百度的点数组生成就没问题了。

  • 2020-03-19 19:15:47

    vue中methods watch和compute的区别和联系

    首先要说,methods,watch和computed都是以函数为基础的,但各自却都不同 而从作用机制和性质上看,methods和watch/computed不太一样,所以我接下来的介绍主要有两个对比: 1.methods和(watch/computed)的对比

  • 2020-03-19 19:50:31

    用vue做的跟随鼠标移动的div

    随鼠标移动的动画效果,之前一直使用angular和react,没怎么接触过vue,先做一个vue的简单例子,然后再整合。

  • 2020-03-20 13:35:55

    随便想到,群聊天的数据库简单设计

    拆分成两个表,一个是消息的流水表,一个是每个人的配置表。 记录每个群下面的这个用户的最后读取的消息last_msg_id,然后在计算消息未读数据。 这样优化之后数据将减少好多,数量是 m+n条数据。不在是成倍增长了。

  • 2020-03-20 13:39:50

    类似与微信朋友圈功能数据库如何实现

    每次发圈子的时候,给关注我的每个uuid,发一个内容id。 大概表的设计就是 uuid,idlist 这样的,idlist是按照时间顺序的。 然后定期删除idlist过多的老圈子。