做习题的小伙伴在做试题的时候需要把Word文档中的习题切图制作成试题,由于没注意到Word转出的图片上有很多水印导致制作的资源很不美观。由于涉及的图片数量庞大几千上万张,如果用PS去处理也够我们UI喝一壶的。于是发扬技术解决一切问题的精神写了个图片批量处理水印程序。

 

效果预览

先看一下原图,是这样的

 

 

 

 

 

用程序处理后的结果是介个样子滴:

 

 

 

 

 

可以看到,水印基本已经无影无踪了。

 

分析

要实现这样的一个程序首先要了解关于图像的基本知识。我们平常所看到的JPG,PNG等图像在显示的时候是以像素为单位的。长300宽400像素的图片所有像素为300×400=120000个像素点。在ARGB的图像表示方法中,每个像素点有ARGB四个通道,

 

A代表透明度,取值范围0~255,

 

R代表三原色中的红,取值范围0~255,

 

G代表三原色中的绿,取值范围0~255,

 

B代表三原色中的蓝,取值范围0~255。

 

所以存储这些数据只需要4个8位二进制在Java中也就是一个int类型就行啦。所以这张图片显示在屏幕上所占用的内存至少是120000×32个字节。每种颜色都有特定的ARGB取值,所以我们要去除水印就是要把图片中特定范围的ARGB取值改为四个通道取值都是255的白色就行了。有了以上理论知识,再结合Java图像处理相关API,根据目标图像的特征提取出适当ARGB取值范围。可以使用qq或者纳克小工,PS等工具查看水印像素所对应的范围。

 

 

 

然后就可以写出一个去水印程序啦。

 

上代码

 


 

1. package com.jzhung.demo.core.image; 
2.   
3. import javax.imageio.ImageIO; 
4. import javax.imageio.ImageWriter; 
5. import javax.imageio.stream.ImageOutputStream; 
6. import javax.net.ssl.HttpsURLConnection; 
7. import java.awt.*; 
8. import java.awt.image.BufferedImage; 
9. import java.io.File; 
10. import java.io.FileFilter; 
11. import java.io.IOException; 
12. import java.net.HttpURLConnection; 
13. import java.net.URL; 
14. import java.util.ArrayList; 
15. import java.util.Iterator; 
16. import java.util.List; 
17. import java.util.Scanner; 
18.   
19. /** 
20.  * Created by Jzhung on 2017/2/27. 
21.  * 文档图片水印处理 
22.  */ 
23. public class ImageConverter { 
24.     private static List<File> fileList = new ArrayList<File>(); 
25.   
26.     public static void main(String[] args) { 
27.         System.out.println("输入需要去水印的图片所在的根目录回车(支持递归子目录):"); 
28.         Scanner input = new Scanner(System.in); 
29.         String dir = input.nextLine().trim(); 
30.   
31.         System.out.println("输入转换后的存储目录:"); 
32.         String saveDir = input.nextLine().trim(); 
33.   
34.         System.out.println("输入y开始"); 
35.         String comfrm = input.nextLine().trim(); 
36.         if (comfrm.equals("y")) { 
37.             convertAllImages(dir, saveDir); 
38.         } else { 
39.             System.out.println("您输入的不是y程序,程序退出"); 
40.         } 
41.   
42.         /*String dir = "E:\\data\\Desktop"; 
43.         String saveDir = "E:\\data\\Desktop-convert";*/ 
44.   
45.         //replaceFolderImages(dir); 
46.         /*String srcFile = "E:\\data\\image\\img38.png"; 
47.         String dstFile = "E:\\data\\image\\img38.png"; 
48.         long begin = System.currentTimeMillis(); 
49.         repleaceColor(srcFile, dstFile); 
50.         long time = System.currentTimeMillis() - begin; 
51.         System.out.println(time);*/ 
52.     } 
53.   
54.     private static void convertAllImages(String dir, String saveDir) { 
55.         File dirFile = new File(dir); 
56.         File saveDirFile = new File(saveDir); 
57.         dir = dirFile.getAbsolutePath(); 
58.         saveDir = saveDirFile.getAbsolutePath(); 
59.         loadImages(new File(dir)); 
60.         for (File file : fileList) { 
61.             String filePath = file.getAbsolutePath(); 
62.   
63.             String dstPath = saveDir + filePath.substring(filePath.indexOf(dir) + dir.length(), filePath.length()); 
64.             System.out.println("converting: " + filePath); 
65.             replaceColor(file.getAbsolutePath(), dstPath); 
66.         } 
67.     } 
68.   
69.     public static void loadImages(File f) { 
70.         if (f != null) { 
71.             if (f.isDirectory()) { 
72.                 File[] fileArray = f.listFiles(); 
73.                 if (fileArray != null) { 
74.                     for (int i = 0; i < fileArray.length; i++) { 
75.                         //递归调用 
76.                         loadImages(fileArray[i]); 
77.                     } 
78.                 } 
79.             } else { 
80.                 String name = f.getName(); 
81.                 if (name.endsWith("png") || name.endsWith("jpg")) { 
82.                     fileList.add(f); 
83.                 } 
84.             } 
85.         } 
86.     } 
87.   
88.     private static void replaceFolderImages(String dir) { 
89.         File dirFile = new File(dir); 
90.         File[] files = dirFile.listFiles(new FileFilter() { 
91.             public boolean accept(File file) { 
92.                 String name = file.getName(); 
93.                 if (name.endsWith("png") || name.endsWith("jpg")) { 
94.                     return true; 
95.                 } 
96.                 return false; 
97.             } 
98.         }); 
99.         for (File img : files) { 
100.             replaceColor(img.getAbsolutePath(), img.getAbsolutePath()); 
101.         } 
102.     } 
103.   
104.     private static void replaceColor(String srcFile, String dstFile) { 
105.         try { 
106.             Color color = new Color(255, 195, 195); 
107.             replaceImageColor(srcFile, dstFile, color, Color.WHITE); 
108.         } catch (IOException e) { 
109.             e.printStackTrace(); 
110.         } 
111.     } 
112.   
113.     public static void replaceImageColor(String file, String dstFile, Color srcColor, Color targetColor) throws IOException { 
114.         URL http; 
115.         if (file.trim().startsWith("https")) { 
116.             http = new URL(file); 
117.             HttpsURLConnection conn = (HttpsURLConnection) http.openConnection(); 
118.             conn.setRequestMethod("GET"); 
119.         } else if (file.trim().startsWith("http")) { 
120.             http = new URL(file); 
121.             HttpURLConnection conn = (HttpURLConnection) http.openConnection(); 
122.             conn.setRequestMethod("GET"); 
123.         } else { 
124.             http = new File(file).toURI().toURL(); 
125.         } 
126.         BufferedImage bi = ImageIO.read(http.openStream()); 
127.         if(bi == null){ 
128.             return; 
129.         } 
130.   
131.         Color wColor = new Color(255, 255, 255); 
132.         for (int i = 0; i < bi.getWidth(); i++) { 
133.             for (int j = 0; j < bi.getHeight(); j++) { 
134.                 //System.out.println(bi.getRGB(i, j)); 
135.                 int color = bi.getRGB(i, j); 
136.                 Color oriColor = new Color(color); 
137.                 int red = oriColor.getRed(); 
138.                 int greed = oriColor.getGreen(); 
139.                 int blue = oriColor.getBlue(); 
140.                 //粉色 
141.                 if (greed < 190 || blue < 190) { 
142.   
143.                 } else { 
144.                     if (red == 255 && greed > 180 && blue > 180) { 
145.                         bi.setRGB(i, j, wColor.getRGB()); 
146.                     } 
147.                 } 
148.             } 
149.         } 
150.         String type = file.substring(file.lastIndexOf(".") + 1, file.length()); 
151.         Iterator<ImageWriter> it = ImageIO.getImageWritersByFormatName(type); 
152.         ImageWriter writer = it.next(); 
153.         File f = new File(dstFile); 
154.         f.getParentFile().mkdirs(); 
155.         ImageOutputStream ios = ImageIO.createImageOutputStream(f); 
156.         writer.setOutput(ios); 
157.         writer.write(bi); 
158.         bi.flush(); 
159.         ios.flush(); 
160.         ios.close(); 
161.     } 
162. }