转载_纯Java代码批量去除图片文字水印

时间:2024-03-30 12:01:52

http://www.oicqzone.com/pc/2017062023844.html

问题

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

 

效果预览

先看一下原图,是这样的

 

 

转载_纯Java代码批量去除图片文字水印

 

 

 

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

 

 

 

转载_纯Java代码批量去除图片文字水印

 

 

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

 

分析

要实现这样的一个程序首先要了解关于图像的基本知识。我们平常所看到的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.     }