http://www.oicqzone.com/pc/2017062023844.html
问题
做习题的小伙伴在做试题的时候需要把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等工具查看水印像素所对应的范围。
然后就可以写出一个去水印程序啦。
上代码
- package com.jzhung.demo.core.image;
- import javax.imageio.ImageIO;
- import javax.imageio.ImageWriter;
- import javax.imageio.stream.ImageOutputStream;
- import javax.net.ssl.HttpsURLConnection;
- import java.awt.*;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.FileFilter;
- import java.io.IOException;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Scanner;
- /**
- * Created by Jzhung on 2017/2/27.
- * 文档图片水印处理
- */
- public class ImageConverter {
- private static List<File> fileList = new ArrayList<File>();
- public static void main(String[] args) {
- System.out.println("输入需要去水印的图片所在的根目录回车(支持递归子目录):");
- Scanner input = new Scanner(System.in);
- String dir = input.nextLine().trim();
- System.out.println("输入转换后的存储目录:");
- String saveDir = input.nextLine().trim();
- System.out.println("输入y开始");
- String comfrm = input.nextLine().trim();
- if (comfrm.equals("y")) {
- convertAllImages(dir, saveDir);
- } else {
- System.out.println("您输入的不是y程序,程序退出");
- }
- /*String dir = "E:\\data\\Desktop";
- String saveDir = "E:\\data\\Desktop-convert";*/
- //replaceFolderImages(dir);
- /*String srcFile = "E:\\data\\image\\img38.png";
- String dstFile = "E:\\data\\image\\img38.png";
- long begin = System.currentTimeMillis();
- repleaceColor(srcFile, dstFile);
- long time = System.currentTimeMillis() - begin;
- System.out.println(time);*/
- }
- private static void convertAllImages(String dir, String saveDir) {
- File dirFile = new File(dir);
- File saveDirFile = new File(saveDir);
- dir = dirFile.getAbsolutePath();
- saveDir = saveDirFile.getAbsolutePath();
- loadImages(new File(dir));
- for (File file : fileList) {
- String filePath = file.getAbsolutePath();
- String dstPath = saveDir + filePath.substring(filePath.indexOf(dir) + dir.length(), filePath.length());
- System.out.println("converting: " + filePath);
- replaceColor(file.getAbsolutePath(), dstPath);
- }
- }
- public static void loadImages(File f) {
- if (f != null) {
- if (f.isDirectory()) {
- File[] fileArray = f.listFiles();
- if (fileArray != null) {
- for (int i = 0; i < fileArray.length; i++) {
- //递归调用
- loadImages(fileArray[i]);
- }
- }
- } else {
- String name = f.getName();
- if (name.endsWith("png") || name.endsWith("jpg")) {
- fileList.add(f);
- }
- }
- }
- }
- private static void replaceFolderImages(String dir) {
- File dirFile = new File(dir);
- File[] files = dirFile.listFiles(new FileFilter() {
- public boolean accept(File file) {
- String name = file.getName();
- if (name.endsWith("png") || name.endsWith("jpg")) {
- return true;
- }
- return false;
- }
- });
- for (File img : files) {
- replaceColor(img.getAbsolutePath(), img.getAbsolutePath());
- }
- }
- private static void replaceColor(String srcFile, String dstFile) {
- try {
- Color color = new Color(255, 195, 195);
- replaceImageColor(srcFile, dstFile, color, Color.WHITE);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static void replaceImageColor(String file, String dstFile, Color srcColor, Color targetColor) throws IOException {
- URL http;
- if (file.trim().startsWith("https")) {
- http = new URL(file);
- HttpsURLConnection conn = (HttpsURLConnection) http.openConnection();
- conn.setRequestMethod("GET");
- } else if (file.trim().startsWith("http")) {
- http = new URL(file);
- HttpURLConnection conn = (HttpURLConnection) http.openConnection();
- conn.setRequestMethod("GET");
- } else {
- http = new File(file).toURI().toURL();
- }
- BufferedImage bi = ImageIO.read(http.openStream());
- if(bi == null){
- return;
- }
- Color wColor = new Color(255, 255, 255);
- for (int i = 0; i < bi.getWidth(); i++) {
- for (int j = 0; j < bi.getHeight(); j++) {
- //System.out.println(bi.getRGB(i, j));
- int color = bi.getRGB(i, j);
- Color oriColor = new Color(color);
- int red = oriColor.getRed();
- int greed = oriColor.getGreen();
- int blue = oriColor.getBlue();
- //粉色
- if (greed < 190 || blue < 190) {
- } else {
- if (red == 255 && greed > 180 && blue > 180) {
- bi.setRGB(i, j, wColor.getRGB());
- }
- }
- }
- }
- String type = file.substring(file.lastIndexOf(".") + 1, file.length());
- Iterator<ImageWriter> it = ImageIO.getImageWritersByFormatName(type);
- ImageWriter writer = it.next();
- File f = new File(dstFile);
- f.getParentFile().mkdirs();
- ImageOutputStream ios = ImageIO.createImageOutputStream(f);
- writer.setOutput(ios);
- writer.write(bi);
- bi.flush();
- ios.flush();
- ios.close();
- }
- }