查看: 1640|回复: 0

[Java代码] Java 给图片和动图添加水印的方法

发表于 2018-5-4 08:00:02

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

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

  1. import java.awt.*;
  2. import java.awt.image.BufferedImage;
  3. import java.io.*;
  4. import javax.imageio.ImageIO;
  5. import javax.swing.ImageIcon;
  6. //这下面是 gif4j 框架的类
  7. import com.gif4j.GifDecoder;
  8. import com.gif4j.GifEncoder;
  9. import com.gif4j.GifImage;
  10. import com.gif4j.GifTransformer;
  11. import com.gif4j.TextPainter;
  12. import com.gif4j.Watermark;
  13. /**
  14. * Created by ZXD on 2018/1/18.
  15. */
  16. public class ImageRemarkUtil {
  17. // 水印透明度
  18. private float alpha = 0.5f;
  19. // 水印横向位置
  20. private int positionWidth = 150;
  21. // 水印纵向位置
  22. private int positionHeight = 300;
  23. //水印宽
  24. private int width = 80;
  25. //水印高
  26. private int height = 80;
  27. // 水印文字字体
  28. private Font font = new Font("宋体", Font.BOLD, 72);
  29. // 水印文字颜色
  30. private Color color = Color.red;
  31. /***********普通图片加水印***********/
  32. /**
  33. *
  34. * @param alpha
  35. * 水印透明度
  36. * @param positionWidth
  37. * 水印横向位置
  38. * @param positionHeight
  39. * 水印纵向位置
  40. * @param font
  41. * 水印文字字体
  42. * @param color
  43. * 水印文字颜色
  44. */
  45. public void setImageMarkOptions(float alpha, int positionWidth,
  46. int positionHeight,int width,int height, Font font, Color color) {
  47. if (alpha != 0.0f)
  48. this.alpha = alpha;
  49. if (positionWidth != 0)
  50. this.positionWidth = positionWidth;
  51. if (positionHeight != 0)
  52. this.positionHeight = positionHeight;
  53. if (height != 0)
  54. this.height = height;
  55. if (width != 0)
  56. this.width = width;
  57. if (font != null)
  58. this.font = font;
  59. if (color != null)
  60. this.color = color;
  61. }
  62. /**
  63. * 给图片添加水印图片
  64. *
  65. * @param iconPath
  66. * 水印图片路径
  67. * @param srcImgPath
  68. * 源图片路径
  69. * @param targerPath
  70. * 目标图片路径
  71. */
  72. public void markImageByIcon(String iconPath, String srcImgPath,
  73. String targerPath) {
  74. markImageByIcon(iconPath, srcImgPath, targerPath, null);
  75. }
  76. /**
  77. * 给图片添加水印图片、可设置水印图片旋转角度
  78. *
  79. * @param iconPath
  80. * 水印图片路径
  81. * @param srcImgPath
  82. * 源图片路径
  83. * @param targerPath
  84. * 目标图片路径
  85. * @param degree
  86. * 水印图片旋转角度
  87. */
  88. public void markImageByIcon(String iconPath, String srcImgPath,
  89. String targerPath, Integer degree) {
  90. OutputStream os = null;
  91. try {
  92. Image srcImg = ImageIO.read(new File(srcImgPath));
  93. BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
  94. srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
  95. // 1、得到画笔对象
  96. Graphics2D g = buffImg.createGraphics();
  97. // 2、设置对线段的锯齿状边缘处理
  98. g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
  99. RenderingHints.VALUE_INTERPOLATION_BILINEAR);
  100. g.drawImage(
  101. srcImg.getScaledInstance(srcImg.getWidth(null),
  102. srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
  103. null);
  104. // 3、设置水印旋转
  105. if (null != degree) {
  106. g.rotate(Math.toRadians(degree),
  107. (double) buffImg.getWidth() / 2,
  108. (double) buffImg.getHeight() / 2);
  109. }
  110. // 4、水印图片的路径 水印图片一般为gif或者png的,这样可设置透明度
  111. ImageIcon imgIcon = new ImageIcon(iconPath);
  112. // 5、得到Image对象。
  113. Image img = imgIcon.getImage();
  114. g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
  115. alpha));
  116. Integer X = srcImg.getWidth(null);
  117. Integer Y = srcImg.getHeight(null);
  118. // 6、水印图片的位置
  119. g.drawImage(img, X-(positionWidth+width), Y-(positionHeight+height),width,height,null);
  120. g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
  121. // 7、释放资源
  122. g.dispose();
  123. // 8、生成图片
  124. os = new FileOutputStream(targerPath);
  125. ImageIO.write(buffImg, "JPG", os);
  126. System.out.println("图片完成添加水印图片");
  127. } catch (Exception e) {
  128. e.printStackTrace();
  129. } finally {
  130. try {
  131. if (null != os)
  132. os.close();
  133. } catch (Exception e) {
  134. e.printStackTrace();
  135. }
  136. }
  137. }
  138. /**
  139. * 给图片添加水印文字
  140. *
  141. * @param logoText
  142. * 水印文字
  143. * @param srcImgPath
  144. * 源图片路径
  145. * @param targerPath
  146. * 目标图片路径
  147. */
  148. public void markImageByText(String logoText, String srcImgPath,
  149. String targerPath) {
  150. markImageByText(logoText, srcImgPath, targerPath, null);
  151. }
  152. /**
  153. * 给图片添加水印文字、可设置水印文字的旋转角度
  154. *
  155. * @param logoText
  156. * @param srcImgPath
  157. * @param targerPath
  158. * @param degree
  159. */
  160. public void markImageByText(String logoText, String srcImgPath,
  161. String targerPath, Integer degree) {
  162. InputStream is = null;
  163. OutputStream os = null;
  164. try {
  165. // 1、源图片
  166. Image srcImg = ImageIO.read(new File(srcImgPath));
  167. BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
  168. srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
  169. // 2、得到画笔对象
  170. Graphics2D g = buffImg.createGraphics();
  171. // 3、设置对线段的锯齿状边缘处理
  172. g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
  173. RenderingHints.VALUE_INTERPOLATION_BILINEAR);
  174. g.drawImage(
  175. srcImg.getScaledInstance(srcImg.getWidth(null),
  176. srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
  177. null);
  178. // 4、设置水印旋转
  179. if (null != degree) {
  180. g.rotate(Math.toRadians(degree),
  181. (double) buffImg.getWidth() / 2,
  182. (double) buffImg.getHeight() / 2);
  183. }
  184. // 5、设置水印文字颜色
  185. g.setColor(color);
  186. // 6、设置水印文字Font
  187. g.setFont(font);
  188. // 7、设置水印文字透明度
  189. g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
  190. alpha));
  191. // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
  192. g.drawString(logoText, positionWidth, positionHeight);
  193. // 9、释放资源
  194. g.dispose();
  195. // 10、生成图片
  196. os = new FileOutputStream(targerPath);
  197. ImageIO.write(buffImg, "JPG", os);
  198. System.out.println("图片完成添加水印文字");
  199. } catch (Exception e) {
  200. e.printStackTrace();
  201. } finally {
  202. try {
  203. if (null != is)
  204. is.close();
  205. } catch (Exception e) {
  206. e.printStackTrace();
  207. }
  208. try {
  209. if (null != os)
  210. os.close();
  211. } catch (Exception e) {
  212. e.printStackTrace();
  213. }
  214. }
  215. }
  216. /*********** 动图加水印 ************/
  217. /**
  218. * 缩放gif图片,直接传的File文件,可设置宽和高
  219. */
  220. public void makeGif(File src, File dest, int width, int height) throws IOException {
  221. GifImage gifImage = GifDecoder.decode(src);// 创建一个GifImage对象.
  222. GifImage resizeIMG = GifTransformer.resize(gifImage, width, height, true);
  223. GifEncoder.encode(resizeIMG, dest);
  224. }
  225. //缩放gif图片,直接传文件路径,可设置宽和高
  226. public void makeGif(String src, String dest, int width, int height) throws IOException {
  227. GifImage gifImage = GifDecoder.decode(new File(src));// 创建一个GifImage对象.
  228. makeGif(new File(src), new File(dest), gifImage.getScreenWidth() / 2,
  229. gifImage.getScreenHeight() / 2);
  230. }
  231. //缩放gif图片,传文件File文件,不可设置宽和高
  232. public void makeGif(File src, File dest) throws IOException {
  233. GifImage gifImage = GifDecoder.decode(src);// 创建一个GifImage对象.
  234. makeGif(src, dest, gifImage.getScreenWidth() / 2, gifImage.getScreenHeight() / 2);
  235. }
  236. //缩放gif图片,传文件路径,不可设置宽和高
  237. public void makeGif(String src, String dest) throws IOException {
  238. makeGif(new File(src), new File(dest));
  239. }
  240. /**
  241. * 动图中加文字水印
  242. */
  243. public void addTextWatermarkToGif(File src, String watermarkText, File dest)throws IOException {
  244. //水印初始化、设置(字体、样式、大小、颜色)
  245. TextPainter textPainter = new TextPainter(new Font("黑体", Font.ITALIC, 12));
  246. textPainter.setOutlinePaint(Color.WHITE);
  247. BufferedImage renderedWatermarkText = textPainter.renderString(watermarkText, true);
  248. //图片对象
  249. GifImage gf = GifDecoder.decode(src);
  250. //获取图片大小
  251. int iw = gf.getScreenWidth();
  252. int ih = gf.getScreenHeight();
  253. //获取水印大小
  254. int tw = renderedWatermarkText.getWidth();
  255. int th = renderedWatermarkText.getHeight();
  256. //水印位置
  257. Point p = new Point();
  258. p.x = iw - tw - 5;
  259. p.y = ih - th - 4;
  260. //加水印
  261. Watermark watermark = new Watermark(renderedWatermarkText, p);
  262. gf = watermark.apply(GifDecoder.decode(src), true);
  263. //输出
  264. GifEncoder.encode(gf, dest);
  265. }
  266. /**
  267. * 动图中加图片水印
  268. */
  269. public void addImageWatermarkToGif(File src, String watermarkPath, File dest){
  270. try{
  271. BufferedImage renderedWatermarkText = ImageIO.read(new File(watermarkPath));
  272. //图片对象
  273. GifImage gf = GifDecoder.decode(src);
  274. //获取图片大小
  275. int iw = gf.getScreenWidth();
  276. int ih = gf.getScreenHeight();
  277. //获取水印大小
  278. int tw = renderedWatermarkText.getWidth();
  279. int th = renderedWatermarkText.getHeight();
  280. //水印位置
  281. Point p = new Point();
  282. p.x = iw-tw-20;
  283. p.y = ih-th-20;
  284. //加水印
  285. Watermark watermark = new Watermark(renderedWatermarkText, p);
  286. //水印透明度
  287. watermark.setTransparency(1);
  288. gf = watermark.apply(GifDecoder.decode(src), false);
  289. //输出
  290. GifEncoder.encode(gf, dest);
  291. } catch (IOException e){
  292. e.printStackTrace();
  293. }
  294. }
  295. public static void main(String[] args) {
  296. //需要加水印图片的路径
  297. String srcImgPath = "d:/1.jpg";
  298. String logoText = "复 印 无 效";
  299. //图片水印的路径
  300. String iconPath = "d:/2.jpg";
  301. //添加完水印文件的输出路径
  302. String targerTextPath = "d:/qie_text.jpg";
  303. String targerTextPath2 = "d:/qie_text_rotate.jpg";
  304. String targerIconPath = "d:/qie_icon.jpg";
  305. String targerIconPath2 = "d:/qie_icon_rotate.jpg";
  306. System.out.println("给图片添加水印文字开始...");
  307. // 给图片添加水印文字
  308. markImageByText(logoText, srcImgPath, targerTextPath);
  309. // 给图片添加水印文字,水印文字旋转-45
  310. markImageByText(logoText, srcImgPath, targerTextPath2, -45);
  311. System.out.println("给图片添加水印文字结束...");
  312. System.out.println("给图片添加水印图片开始...");
  313. setImageMarkOptions(0.3f, 1, 1, null, null);
  314. // 给图片添加水印图片
  315. markImageByIcon(iconPath, srcImgPath, targerIconPath);
  316. // 给图片添加水印图片,水印图片旋转-45
  317. markImageByIcon(iconPath, srcImgPath, targerIconPath2, -45);
  318. System.out.println("给图片添加水印图片结束...");
  319. //动图添加水印(添加水印动图文件,添加的水印,添加完输出文件)
  320. addTextWatermarkToGif(new File("d:\\10.gif"), "复 印 无 效", new File("d:\\11.gif"));
  321. addImageWatermarkToGif(new File("d:\\gif\\10.gif"), "d:\\gif\\3.png", new File("d:\\gif\\4.gif"));
  322. }
  323. }
复制代码

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

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

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



回复

使用道具 举报