Java 给图片和动图添加水印的方法

时间:2022-02-14 11:44:54

这两天根据需求在做图片上传添加水印,实话说重来不知道java还可以这样操作,既然有个这要求我就去找资料研究了一番,现在把它分享一下,希望能帮到有需要的兄弟。

给普通图片添加水印和给动图添加水印是不一样的,给普通图片添加水印用的是java自带的方法写的,给动图使用了gif4j框架,这个框架在csdn里面很多可以下载,建议下载破解版的,因为原来的jar包会有自带的一个水印是去不了的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
import java.awt.*;
import java.awt.image.bufferedimage;
import java.io.*; 
import javax.imageio.imageio;
import javax.swing.imageicon;  
//这下面是 gif4j 框架的类
import com.gif4j.gifdecoder;
import com.gif4j.gifencoder;
import com.gif4j.gifimage;
import com.gif4j.giftransformer;
import com.gif4j.textpainter;
import com.gif4j.watermark;  
/**
 * created by zxd on 2018/1/18.
 */
public class imageremarkutil {
  // 水印透明度
  private float alpha = 0.5f;
  // 水印横向位置
  private int positionwidth = 150;
  // 水印纵向位置
  private int positionheight = 300;
  //水印宽
  private int width = 80;
  //水印高
  private int height = 80;
  // 水印文字字体
  private font font = new font("宋体", font.bold, 72);
  // 水印文字颜色
  private color color = color.red;
  
  
  /***********普通图片加水印***********/
  
  /**
   *
   * @param alpha
   *      水印透明度
   * @param positionwidth
   *      水印横向位置
   * @param positionheight
   *      水印纵向位置
   * @param font
   *      水印文字字体
   * @param color
   *      水印文字颜色
   */
  public void setimagemarkoptions(float alpha, int positionwidth,
                      int positionheight,int width,int height, font font, color color) {
    if (alpha != 0.0f)
      this.alpha = alpha;
    if (positionwidth != 0)
      this.positionwidth = positionwidth;
    if (positionheight != 0)
      this.positionheight = positionheight;
    if (height != 0)
      this.height = height;
    if (width != 0)
      this.width = width;
    if (font != null)
      this.font = font;
    if (color != null)
      this.color = color;
  }
  
  /**
   * 给图片添加水印图片
   *
   * @param iconpath
   *      水印图片路径
   * @param srcimgpath
   *      源图片路径
   * @param targerpath
   *      目标图片路径
   */
  public void markimagebyicon(string iconpath, string srcimgpath,
                    string targerpath) {
    markimagebyicon(iconpath, srcimgpath, targerpath, null);
  }
  
  /**
   * 给图片添加水印图片、可设置水印图片旋转角度
   *
   * @param iconpath
   *      水印图片路径
   * @param srcimgpath
   *      源图片路径
   * @param targerpath
   *      目标图片路径
   * @param degree
   *      水印图片旋转角度
   */
  public void markimagebyicon(string iconpath, string srcimgpath,
                    string targerpath, integer degree) {
    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);
  
      // 1、得到画笔对象
      graphics2d g = buffimg.creategraphics();
  
      // 2、设置对线段的锯齿状边缘处理
      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);
      // 3、设置水印旋转
      if (null != degree) {
        g.rotate(math.toradians(degree),
            (double) buffimg.getwidth() / 2,
            (double) buffimg.getheight() / 2);
      }
  
      // 4、水印图片的路径 水印图片一般为gif或者png的,这样可设置透明度
      imageicon imgicon = new imageicon(iconpath);
  
      // 5、得到image对象。
      image img = imgicon.getimage();
  
      g.setcomposite(alphacomposite.getinstance(alphacomposite.src_atop,
          alpha));
  
      integer x = srcimg.getwidth(null);
  
      integer y = srcimg.getheight(null);
  
      // 6、水印图片的位置
      g.drawimage(img, x-(positionwidth+width), y-(positionheight+height),width,height,null);
  
      g.setcomposite(alphacomposite.getinstance(alphacomposite.src_over));
      // 7、释放资源
      g.dispose();
  
      // 8、生成图片
      os = new fileoutputstream(targerpath);
      imageio.write(buffimg, "jpg", os);
  
      system.out.println("图片完成添加水印图片");
  
    } catch (exception e) {
      e.printstacktrace();
    } finally {
      try {
        if (null != os)
          os.close();
      } catch (exception e) {
        e.printstacktrace();
      }
    }
  }
  
  /**
   * 给图片添加水印文字
   *
   * @param logotext
   *      水印文字
   * @param srcimgpath
   *      源图片路径
   * @param targerpath
   *      目标图片路径
   */
  public void markimagebytext(string logotext, string srcimgpath,
                    string targerpath) {
    markimagebytext(logotext, srcimgpath, targerpath, null);
  }
  
  /**
   * 给图片添加水印文字、可设置水印文字的旋转角度
   *
   * @param logotext
   * @param srcimgpath
   * @param targerpath
   * @param degree
   */
  public void markimagebytext(string logotext, string srcimgpath,
                    string targerpath, integer degree) {
  
    inputstream is = null;
    outputstream os = null;
    try {
      // 1、源图片
      image srcimg = imageio.read(new file(srcimgpath));
      bufferedimage buffimg = new bufferedimage(srcimg.getwidth(null),
          srcimg.getheight(null), bufferedimage.type_int_rgb);
  
      // 2、得到画笔对象
      graphics2d g = buffimg.creategraphics();
      // 3、设置对线段的锯齿状边缘处理
      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);
      // 4、设置水印旋转
      if (null != degree) {
        g.rotate(math.toradians(degree),
            (double) buffimg.getwidth() / 2,
            (double) buffimg.getheight() / 2);
      }
      // 5、设置水印文字颜色
      g.setcolor(color);
      // 6、设置水印文字font
      g.setfont(font);
      // 7、设置水印文字透明度
      g.setcomposite(alphacomposite.getinstance(alphacomposite.src_atop,
          alpha));
      // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
      g.drawstring(logotext, positionwidth, positionheight);
      // 9、释放资源
      g.dispose();
      // 10、生成图片
      os = new fileoutputstream(targerpath);
      imageio.write(buffimg, "jpg", os);
  
      system.out.println("图片完成添加水印文字");
  
    } catch (exception e) {
      e.printstacktrace();
    } finally {
      try {
        if (null != is)
          is.close();
      } catch (exception e) {
        e.printstacktrace();
      }
      try {
        if (null != os)
          os.close();
      } catch (exception e) {
        e.printstacktrace();
      }
    }
  }
   
  /*********** 动图加水印 ************/
  
  /**
   * 缩放gif图片,直接传的file文件,可设置宽和高
   */
  public void makegif(file src, file dest, int width, int height) throws ioexception {
      gifimage gifimage = gifdecoder.decode(src);// 创建一个gifimage对象.
      gifimage resizeimg = giftransformer.resize(gifimage, width, height, true);
      gifencoder.encode(resizeimg, dest);
    }
   //缩放gif图片,直接传文件路径,可设置宽和高
  public void makegif(string src, string dest, int width, int height) throws ioexception {
    gifimage gifimage = gifdecoder.decode(new file(src));// 创建一个gifimage对象.  
    makegif(new file(src), new file(dest), gifimage.getscreenwidth() / 2,
        gifimage.getscreenheight() / 2);
  
  }
   //缩放gif图片,传文件file文件,不可设置宽和高
  public void makegif(file src, file dest) throws ioexception {  
    gifimage gifimage = gifdecoder.decode(src);// 创建一个gifimage对象.  
    makegif(src, dest, gifimage.getscreenwidth() / 2, gifimage.getscreenheight() / 2);  
  }
   //缩放gif图片,传文件路径,不可设置宽和高
  public void makegif(string src, string dest) throws ioexception {  
    makegif(new file(src), new file(dest));  
  }
  
  /**
   * 动图中加文字水印
   */
  public void addtextwatermarktogif(file src, string watermarktext, file dest)throws ioexception {  
    //水印初始化、设置(字体、样式、大小、颜色)  
    textpainter textpainter = new textpainter(new font("黑体", font.italic, 12));  
    textpainter.setoutlinepaint(color.white);  
    bufferedimage renderedwatermarktext = textpainter.renderstring(watermarktext, true);  
    //图片对象
    gifimage gf = gifdecoder.decode(src);  
    //获取图片大小  
    int iw = gf.getscreenwidth();  
    int ih = gf.getscreenheight();  
    //获取水印大小
      int tw = renderedwatermarktext.getwidth();  
    int th = renderedwatermarktext.getheight();  
    //水印位置  
    point p = new point();
    p.x = iw - tw - 5;
    p.y = ih - th - 4;
      //加水印
    watermark watermark = new watermark(renderedwatermarktext, p);
    gf = watermark.apply(gifdecoder.decode(src), true);
    //输出
    gifencoder.encode(gf, dest);
  }
  
  /**
   * 动图中加图片水印
   */
  public void addimagewatermarktogif(file src, string watermarkpath, file dest){
  
    try{
  
      bufferedimage renderedwatermarktext = imageio.read(new file(watermarkpath));
  
      //图片对象
      gifimage gf = gifdecoder.decode(src);
  
      //获取图片大小
      int iw = gf.getscreenwidth();
      int ih = gf.getscreenheight();
  
      //获取水印大小
      int tw = renderedwatermarktext.getwidth();
      int th = renderedwatermarktext.getheight();
  
      //水印位置
      point p = new point();
      p.x = iw-tw-20;
      p.y = ih-th-20;
  
      //加水印
      watermark watermark = new watermark(renderedwatermarktext, p);
      //水印透明度
      watermark.settransparency(1);
      gf = watermark.apply(gifdecoder.decode(src), false);
      //输出
      gifencoder.encode(gf, dest);
    } catch (ioexception e){
      e.printstacktrace();
    }
  
  
  public static void main(string[] args) {
    //需要加水印图片的路径
    string srcimgpath = "d:/1.jpg";
    string logotext = "复 印 无 效";
    //图片水印的路径
    string iconpath = "d:/2.jpg";
  
     //添加完水印文件的输出路径
    string targertextpath = "d:/qie_text.jpg";
    string targertextpath2 = "d:/qie_text_rotate.jpg";
    string targericonpath = "d:/qie_icon.jpg";
    string targericonpath2 = "d:/qie_icon_rotate.jpg";
  
    system.out.println("给图片添加水印文字开始...");
    // 给图片添加水印文字
    markimagebytext(logotext, srcimgpath, targertextpath);
    // 给图片添加水印文字,水印文字旋转-45
    markimagebytext(logotext, srcimgpath, targertextpath2, -45);
    system.out.println("给图片添加水印文字结束...");
  
    system.out.println("给图片添加水印图片开始...");
    setimagemarkoptions(0.3f, 1, 1, null, null);
     // 给图片添加水印图片
    markimagebyicon(iconpath, srcimgpath, targericonpath);
    // 给图片添加水印图片,水印图片旋转-45
    markimagebyicon(iconpath, srcimgpath, targericonpath2, -45);
    system.out.println("给图片添加水印图片结束...");
  
    //动图添加水印(添加水印动图文件,添加的水印,添加完输出文件)
    addtextwatermarktogif(new file("d:\\10.gif"), "复 印 无 效", new file("d:\\11.gif"));
    addimagewatermarktogif(new file("d:\\gif\\10.gif"), "d:\\gif\\3.png", new file("d:\\gif\\4.gif"));  
  }  
}

这里面有普通图片添加水印和动图添加水印,普通图片添加水印方法如果传的是动图能添加成功,但是动图就成静态的了,动图添加水印方法如果传的是普通图片,会直接报错了。

这些我在做的时候都有试过,现在就当记笔记记录在此,也希望能帮助到有需要的兄弟。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/ZXD_ZSL/article/details/80037970