开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 230|回复: 6
打印 上一主题 下一主题
收起左侧

[其它求助] 求图片去水印源码

[复制链接]
结帖率:88% (22/25)
跳转到指定楼层
楼主
发表于 2025-6-14 11:51:57 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式   江西省吉安市
100精币


不知道是什么语言编写的pdf去水印软件,这个软件收费。通过选取多个水印颜色,实现去水印。有没有相关源码参考的。不限语言,只要功能完整。


回答提醒:如果本帖被关闭无法回复,您有更好的答案帮助楼主解决,请发表至 源码区 可获得加分喔。
友情提醒:本版被采纳的主题可在 申请荣誉值 页面申请荣誉值,获得 1点 荣誉值,荣誉值可兑换荣誉会员、终身vip用户组。
快捷通道:申请荣誉值无答案申请取消悬赏投诉有答案未采纳为最佳

结帖率:100% (8/8)

签到天数: 14 天

沙发
发表于 2025-6-14 11:53:52 | 只看该作者   安徽省六安市
他这个只是将指定颜色换成白色吧  如果内容也有相似的样色  或者水印改在正文上不还是不行么
回复

使用道具 举报

签到天数: 14 天

板凳
发表于 2025-6-14 14:39:21 | 只看该作者   河南省驻马店市
使用OpenCV 库 可以完美达到效果!
回复

使用道具 举报

地板
发表于 2025-6-14 15:54:39 | 只看该作者   四川省攀枝花市
他这个只是将指定颜色换成白色吧  如果内容也有相似的样色  或者水印改在正文上不还是不行么
回复

使用道具 举报

结帖率:33% (1/3)

签到天数: 13 天

地下
发表于 2025-6-14 22:58:42 | 只看该作者   福建省厦门市
给你个思路,如果水印背景是干净的,吧图片二值化,对比度调高,识别出水印区域,然后替换之前没变颜色的底图颜色
回复

使用道具 举报

结帖率:98% (44/45)

签到天数: 12 天

6
发表于 2025-6-14 23:07:30 | 只看该作者   浙江省湖州市
贴张图片出来看看
回复

使用道具 举报

结帖率:57% (12/21)

签到天数: 6 天

7
发表于 2025-6-15 10:02:18 | 只看该作者   浙江省湖州市
### 图片去水印源码实现方案

基于颜色选择的去水印原理是识别特定颜色范围内的像素,然后通过周围像素进行填充修复。以下提供多种语言的实现方案,包括图片和PDF去水印的不同处理方式。


### 一、Python实现方案(图片去水印)

Python的PIL和OpenCV库非常适合实现基于颜色的去水印功能:

```python
import cv2
import numpy as np
from PIL import Image, ImageDraw

def remove_watermark_by_color(image_path, output_path, color_ranges, radius=5):
    """
    通过颜色范围去除图片水印
    image_path: 输入图片路径
    color_ranges: 水印颜色范围列表,每个元素为[(min_b, min_g, min_r), (max_b, max_g, max_r)]
    radius: 修复半径
    """
    # 读取图片
    img = cv2.imread(image_path)
    if img is None:
        print(f"无法读取图片: {image_path}")
        return False
   
    # 转换为HSV颜色空间(更适合颜色识别)
    hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
   
    # 创建掩码
    mask = np.zeros_like(hsv_img[:, :, 0])
    for color_range in color_ranges:
        min_color, max_color = color_range
        # 生成当前颜色范围的掩码
        current_mask = cv2.inRange(hsv_img, np.array(min_color), np.array(max_color))
        mask = cv2.bitwise_or(mask, current_mask)
   
    # 寻找水印区域轮廓
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
   
    # 使用修复算法去除水印
    result = cv2.inpaint(img, mask, radius, cv2.INPAINT_NS)
   
    # 保存结果
    cv2.imwrite(output_path, result)
    return True

def select_watermark_color(image_path):
    """交互式选择水印颜色范围"""
    img = cv2.imread(image_path)
    if img is None:
        print(f"无法读取图片: {image_path}")
        return []
   
    # 显示图片并允许用户点击选择颜色
    cv2.imshow("选择水印颜色,点击完成后按ESC退出", img)
    color_points = []
   
    def mouse_callback(event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            # 获取点击处的BGR颜色
            b, g, r = img[y, x]
            color_points.append((b, g, r))
            print(f"选择颜色: B={b}, G={g}, R={r}")
   
    cv2.setMouseCallback("选择水印颜色,点击完成后按ESC退出", mouse_callback)
   
    while True:
        if cv2.waitKey(1) == 27:  # ESC键退出
            break
   
    cv2.destroyAllWindows()
   
    # 生成颜色范围(以选择颜色为中心,上下浮动20)
    color_ranges = []
    for b, g, r in color_points:
        min_color = (max(0, b-20), max(0, g-20), max(0, r-20))
        max_color = (min(255, b+20), min(255, g+20), min(255, r+20))
        color_ranges.append((min_color, max_color))
   
    return color_ranges

# 使用示例
if __name__ == "__main__":
    image_path = "watermarked_image.jpg"
    output_path = "watermark_removed.jpg"
   
    # 交互式选择颜色
    color_ranges = select_watermark_color(image_path)
   
    if color_ranges:
        # 去除水印
        success = remove_watermark_by_color(image_path, output_path, color_ranges)
        if success:
            print(f"水印去除完成,结果保存至: {output_path}")
        else:
            print("水印去除失败")
```


### 二、Java实现方案(图片去水印)

使用Java的OpenCV绑定库实现类似功能:

```java
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

public class WatermarkRemover {
    static {
        // 加载OpenCV库
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }
   
    public static void main(String[] args) {
        String imagePath = "watermarked_image.jpg";
        String outputPath = "watermark_removed.jpg";
        
        try {
            // 交互式选择颜色
            List<ColorRange> colorRanges = selectWatermarkColor(imagePath);
            
            if (!colorRanges.isEmpty()) {
                // 去除水印
                boolean success = removeWatermarkByColor(imagePath, outputPath, colorRanges);
                if (success) {
                    System.out.println("水印去除完成,结果保存至: " + outputPath);
                } else {
                    System.out.println("水印去除失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   
    static List<ColorRange> selectWatermarkColor(String imagePath) {
        Mat image = Imgcodecs.imread(imagePath);
        if (image.empty()) {
            System.out.println("无法读取图片: " + imagePath);
            return new ArrayList<>();
        }
        
        // 转换为AWT图像用于显示
        MatOfByte matOfByte = new MatOfByte();
        Imgcodecs.imencode(".jpg", image, matOfByte);
        byte[] byteArray = matOfByte.toArray();
        ImageIcon icon = new ImageIcon(byteArray);
        
        // 创建窗口
        JFrame frame = new JFrame("选择水印颜色,点击完成后关闭窗口");
        frame.setSize(icon.getIconWidth(), icon.getIconHeight() + 50);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        
        JLabel label = new JLabel(icon);
        frame.add(label);
        
        final List<ColorRange> colorRanges = new ArrayList<>();
        
        label.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                // 获取点击处的BGR颜色
                int x = e.getX();
                int y = e.getY();
               
                if (x >= 0 && x < image.cols() && y >= 0 && y < image.rows()) {
                    double[] pixel = image.get(y, x);
                    int b = (int) pixel[0];
                    int g = (int) pixel[1];
                    int r = (int) pixel[2];
                    
                    System.out.println("选择颜色: B=" + b + ", G=" + g + ", R=" + r);
                    
                    // 生成颜色范围(上下浮动20)
                    int minB = Math.max(0, b - 20);
                    int minG = Math.max(0, g - 20);
                    int minR = Math.max(0, r - 20);
                    int maxB = Math.min(255, b + 20);
                    int maxG = Math.min(255, g + 20);
                    int maxR = Math.min(255, r + 20);
                    
                    colorRanges.add(new ColorRange(new Scalar(minB, minG, minR), new Scalar(maxB, maxG, maxR)));
                }
            }
        });
        
        frame.setVisible(true);
        
        // 等待窗口关闭
        try {
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return colorRanges;
    }
   
    static boolean removeWatermarkByColor(String imagePath, String outputPath, List<ColorRange> colorRanges) {
        Mat image = Imgcodecs.imread(imagePath);
        if (image.empty()) {
            System.out.println("无法读取图片: " + imagePath);
            return false;
        }
        
        // 转换为HSV颜色空间
        Mat hsvImage = new Mat();
        Imgproc.cvtColor(image, hsvImage, Imgproc.COLOR_BGR2HSV);
        
        // 创建掩码
        Mat mask = Mat.zeros(image.size(), CvType.CV_8UC1);
        for (ColorRange range : colorRanges) {
            Mat currentMask = new Mat();
            Core.inRange(hsvImage, range.minColor, range.maxColor, currentMask);
            Core.bitwise_or(mask, currentMask, mask);
        }
        
        // 寻找轮廓并填充
        List<MatOfPoint> contours = new ArrayList<>();
        Mat hierarchy = new Mat();
        Imgproc.findContours(mask, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
        
        // 使用修复算法去除水印
        Mat result = new Mat();
        Imgproc.inpaint(image, mask, result, 5, Imgproc.INPAINT_NS);
        
        // 保存结果
        return Imgcodecs.imwrite(outputPath, result);
    }
   
    static class ColorRange {
        Scalar minColor;
        Scalar maxColor;
        
        ColorRange(Scalar minColor, Scalar maxColor) {
            this.minColor = minColor;
            this.maxColor = maxColor;
        }
    }
}
```


### 三、C++实现方案(图片去水印)

使用C++和OpenCV实现高性能去水印:

```cpp
#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>
#include <string>

struct ColorRange {
    cv::Scalar minColor;
    cv::Scalar maxColor;
   
    ColorRange(cv::Scalar min, cv::Scalar max) : minColor(min), maxColor(max) {}
};

std::vector<ColorRange> selectWatermarkColor(const std::string& imagePath) {
    cv::Mat image = cv::imread(imagePath);
    if (image.empty()) {
        std::cerr << "无法读取图片: " << imagePath << std::endl;
        return {};
    }
   
    cv::namedWindow("选择水印颜色,点击完成后按ESC退出", cv::WINDOW_NORMAL);
    cv::imshow("选择水印颜色,点击完成后按ESC退出", image);
   
    std::vector<ColorRange> colorRanges;
   
    auto mouseCallback = [&](int event, int x, int y, int flags, void* userdata) {
        if (event == cv::EVENT_LBUTTONDOWN) {
            if (x >= 0 && x < image.cols && y >= 0 && y < image.rows) {
                cv::Vec3b pixel = image.at<cv::Vec3b>(y, x);
                int b = pixel[0];
                int g = pixel[1];
                int r = pixel[2];
               
                std::cout << "选择颜色: B=" << (int)b << ", G=" << (int)g << ", R=" << (int)r << std::endl;
               
                // 生成颜色范围(上下浮动20)
                int minB = std::max(0, b - 20);
                int minG = std::max(0, g - 20);
                int minR = std::max(0, r - 20);
                int maxB = std::min(255, b + 20);
                int maxG = std::min(255, g + 20);
                int maxR = std::min(255, r + 20);
               
                colorRanges.emplace_back(cv::Scalar(minB, minG, minR), cv::Scalar(maxB, maxG, maxR));
            }
        }
    };
   
    cv::setMouseCallback("选择水印颜色,点击完成后按ESC退出", mouseCallback);
   
    while (true) {
        if (cv::waitKey(1) == 27) { // ESC键退出
            break;
        }
    }
   
    cv::destroyAllWindows();
    return colorRanges;
}

bool removeWatermarkByColor(const std::string& imagePath, const std::string& outputPath, const std::vector<ColorRange>& colorRanges) {
    cv::Mat image = cv::imread(imagePath);
    if (image.empty()) {
        std::cerr << "无法读取图片: " << imagePath << std::endl;
        return false;
    }
   
    // 转换为HSV颜色空间
    cv::Mat hsvImage;
    cv::cvtColor(image, hsvImage, cv::COLOR_BGR2HSV);
   
    // 创建掩码
    cv::Mat mask = cv::Mat::zeros(image.size(), CV_8UC1);
    for (const auto& range : colorRanges) {
        cv::Mat currentMask;
        cv::inRange(hsvImage, range.minColor, range.maxColor, currentMask);
        cv::bitwise_or(mask, currentMask, mask);
    }
   
    // 寻找轮廓
    std::vector<std::vector<cv::Point>> contours;
    std::vector<cv::Vec4i> hierarchy;
    cv::findContours(mask, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
   
    // 使用修复算法去除水印
    cv::Mat result;
    cv::inpaint(image, mask, result, 5, cv::INPAINT_NS);
   
    // 保存结果
    return cv::imwrite(outputPath, result);
}

int main() {
    std::string imagePath = "watermarked_image.jpg";
    std::string outputPath = "watermark_removed.jpg";
   
    // 交互式选择颜色
    std::vector<ColorRange> colorRanges = selectWatermarkColor(imagePath);
   
    if (!colorRanges.empty()) {
        // 去除水印
        bool success = removeWatermarkByColor(imagePath, outputPath, colorRanges);
        if (success) {
            std::cout << "水印去除完成,结果保存至: " << outputPath << std::endl;
        } else {
            std::cout << "水印去除失败" << std::endl;
        }
    }
   
    return 0;
}
```


### 四、PDF去水印方案(Python)

PDF去水印与图片不同,需要处理矢量图形,以下是基于PyMuPDF的实现:

```python
import fitz  # PyMuPDF

def remove_watermark_from_pdf(input_path, output_path, watermark_color_ranges=None):
    """
    从PDF中去除水印
    input_path: 输入PDF路径
    output_path: 输出PDF路径
    watermark_color_ranges: 水印颜色范围,未提供时尝试自动检测
    """
    doc = fitz.open(input_path)
   
    for page in doc:
        # 获取页面中的所有对象
        for inst in page.get_images():
            xref = inst[0]
            image = doc.extract_image(xref)
            image_bytes = image["image"]
            
            # 转换为PIL图像进行颜色检测
            from PIL import Image
            from io import BytesIO
            
            img = Image.open(BytesIO(image_bytes))
            img = img.convert("RGB")
            
            # 检查是否为水印(简化判断:假设水印颜色较浅且重复出现)
            is_watermark = False
            if watermark_color_ranges:
                # 根据颜色范围判断
                width, height = img.size
                pixel_count = 0
                for y in range(height):
                    for x in range(width):
                        r, g, b = img.getpixel((x, y))
                        for color_range in watermark_color_ranges:
                            min_r, min_g, min_b = color_range[0]
                            max_r, max_g, max_b = color_range[1]
                            if min_r <= r <= max_r and min_g <= g <= max_g and min_b <= b <= max_b:
                                pixel_count += 1
                                break
               
                # 如果大部分像素属于水印颜色范围,则认为是水印
                if pixel_count > width * height * 0.3:
                    is_watermark = True
            else:
                # 自动检测(简化:亮度高于阈值且颜色单一)
                colors = img.getdata()
                light_pixels = sum(1 for r, g, b in colors if (r + g + b) / 3 > 200)
                if light_pixels > len(colors) * 0.5:
                    is_watermark = True
            
            # 如果是水印,则删除该图像
            if is_watermark:
                page.delete_image(xref)
   
    # 保存修改后的PDF
    doc.save(output_path)
    doc.close()
    return True

# 使用示例
if __name__ == "__main__":
    input_pdf = "watermarked.pdf"
    output_pdf = "watermark_removed.pdf"
   
    # 可选:指定水印颜色范围
    # watermark_colors = [((200, 200, 200), (255, 255, 255))]  # 浅灰色范围
    # remove_watermark_from_pdf(input_pdf, output_pdf, watermark_colors)
   
    # 自动检测
    remove_watermark_from_pdf(input_pdf, output_pdf)
    print(f"PDF水印去除完成,保存至: {output_pdf}")
```


### 实现原理说明

1. **颜色识别**:通过HSV颜色空间更准确地识别水印颜色范围,比RGB更适合颜色筛选
2. **区域修复**:使用OpenCV的inpaint函数,通过周围像素智能填充水印区域
3. **交互式选择**:提供鼠标点击选择颜色的功能,方便用户定位水印颜色
4. **PDF处理**:PDF去水印通过分析图像对象的颜色特征来判断并删除水印图像

### 使用注意事项

1. 水印去除效果取决于水印与背景的差异,纯色水印效果最佳
2. 复杂背景或半透明水印可能需要调整颜色范围和修复半径
3. PDF去水印可能需要结合文本分析(如检测重复文本模式)提高准确性
4. 商业软件通常有更复杂的算法(如机器学习预测),上述代码为基础实现

这些代码提供了完整的功能框架,你可以根据实际需求调整颜色检测算法和修复参数,以获得更好的去水印效果。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报QQ: 793400750,邮箱:[email protected]
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表