最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用python去除PDF簡單水印的示例

 更新時間:2024年03月13日 10:34:56   作者:窮儒公羊  
最近在下載PDF書籍的時候,發(fā)現(xiàn)有些PDF有水印,于是就尋思著能不能用Python去除這些討厭的水印,PDF主要有兩種類型,一種是文字版,另外一種就是掃描版(圖片),這個去除水印主要就是針對掃描版的PDF,所以本文介紹了如何使用python去除PDF簡單水印,需要的朋友可以參考下

前言

最近在下載PDF書籍的時候,發(fā)現(xiàn)有些PDF有水印,于是就尋思著能不能用Python去除這些討厭的水印

一、PDF文件

關(guān)于PDF文件,想必大家都很熟悉了,這里就不過多的介紹了。PDF主要有兩種類型,一種是文字版,另外一種就是掃描版(圖片)。這個去除水印主要就是針對掃描版的PDF

二、思路整理

在開始寫代碼之前,先捋一下實現(xiàn)的思路

1、分割圖片

對于一個PDF文件,我們只需要圖片信息就可以了,所以首先需要先提取里邊的圖片,再把圖片存在一個目錄下。這里需要用到fitz模塊,直接安裝即可,如下:

pip install PyMuPDF

模塊安裝完之后,代碼就很簡單了,只需要注意一下圖片按順序命名即可,如下:

def split_pdf(file_path, out_path):
    """
    切割pdf為圖片
    :param file_path: pdf路徑
    :param out_path: 輸出圖片路徑
    :return: 輸出路徑
    """
    pdf = fitz.open(file_path)
    count = 0
    print("##### 開始保存切割圖片 #####")
    for page in pdf:
        image_list = page.get_images()
        for img_info in image_list:
            pix = fitz.Pixmap(pdf, img_info[0])
            pix.save(os.path.join(out_path, '%d.jpg' % count))
            count += 1
    print("##### 保存切割圖片完畢 #####")
    print("##### {0} 包含 {1} 張圖片 #####".format(file_path, count))
    return out_path

2、去除水印

分割完圖片后,接下來的問題也隨之而來了,要如何區(qū)分水印和正常圖片? 要替換成什么? 先來看第一個問題,如何區(qū)分水印

  • 按水印位置
    這個問題,最直觀的想法就是根據(jù)水印的位置以及水印的大小,進行替換就可以。但是這樣存在問題,首先就是不通用(PDF水印的位置可能不一樣),再者就是水印和字混在一起就不好弄了

像這種水印,坐標和大小是可以去除的

在這里插入圖片描述

像這種字和水印混在一起就難辦了

在這里插入圖片描述

在這里插入圖片描述

  • 按顏色
    我們在觀察下水印,發(fā)現(xiàn)水印的顏色一般偏亮一點,而字都是偏暗色的(黑色、灰色)。我們可以根據(jù)顏色將亮一點的顏色都替換掉。但這種方式也有問題,如果是彩色的,就夠嗆了

對于第二個問題:要替換成什么? 如果只有簡單的顏色(黑白灰等),我們直接把水印替換成白色即可

接下來來看下代碼吧,這里需要用到PIL模塊,直接安裝就行了,如下:

pip install pillow

思路有了,代碼就簡單了,如下:

def get_image_arr(img):
    """
    獲取圖片三色數(shù)組
    :param img:圖片
    :return: 圖片編碼、三色數(shù)組
    """
    img_arr = np.asarray(img, dtype=np.double)
    # 分離通道
    r_img = img_arr[:, :, 0].copy()
    g_img = img_arr[:, :, 1].copy()
    b_img = img_arr[:, :, 2].copy()
    img = r_img * 256 * 256 + g_img * 256 + b_img
    return img, r_img, g_img, b_img


def replace_clr_color(img, src_clr, dst_clr):
    """
    通過矩陣操作顏色替換程序
    @param  img:    圖像矩陣
    @param  src_clr:    需要替換的顏色(r,g,b)
    @param  dst_clr:    目標顏色        (r,g,b)
    @return             替換后的圖像矩陣
    """

    img, r_img, g_img, b_img = get_image_arr(img)
    src_color = src_clr[0] * 256 * 256 + src_clr[1] * 256 + src_clr[2]

    # 索引并替換顏色
    r_img[img == src_color] = dst_clr[0]
    g_img[img == src_color] = dst_clr[1]
    b_img[img == src_color] = dst_clr[2]

    return compound_img(r_img, g_img, b_img)


def compound_img(r_img, g_img, b_img):
    """
    合并圖片
    :param r_img: 紅色
    :param g_img: 綠色
    :param b_img: 藍色
    :return: 圖片
    """
    # 合并通道
    dst_img = np.array([r_img, g_img, b_img], dtype=np.uint8)
    # 將數(shù)據(jù)轉(zhuǎn)換為圖像數(shù)據(jù)(h,w,c)
    dst_img = dst_img.transpose(1, 2, 0)
    return dst_img


def replace_pure_color(img, src_color, dst_color):
    """
    通過矩陣操作顏色替換程序(純色)
    :param img: 圖像矩陣
    :param src_color: 需要替換的顏色
    :param dst_color: 目標顏色
    :return: 圖片
    """

    img, r_img, g_img, b_img = get_image_arr(img)
    src_color = src_color * 256 * 256 + src_color * 256 + src_color
    # 索引并替換顏色
    r_img[img >= src_color] = dst_color
    g_img[img >= src_color] = dst_color
    b_img[img >= src_color] = dst_color

    return compound_img(r_img, g_img, b_img)

def wipe_watermark(img_file, start_color):
    """
    去除圖片水印
    :param start_color: 顏色起始替換位置
    :param img_file: 圖片文件
    :return:
    """

    img = replace_pure_color(Image.open(img_file).convert('RGB'), start_color, 255)
    res_img = Image.fromarray(img)
    res_img.save(img_file)

3、替換圖片

保存完去除水印后的圖片,接下來只要把他一個個替換進去就行了

由于原始PDF文件可以有其他東西(書簽等),所以我們先把原始文件讀取進去,在進行替換,代碼如下:

def save_pdf(src_pdf, dest_pdf, file_list):
    """
    生成最終pdf文件
    :param src_pdf: 源文件
    :param dest_pdf: 目標文件
    :param file_list: 圖片列表
    :return:
    """
    pdf = fitz.open(src_pdf)
    index = 0
    try:
        for page in pdf:
            # 去除超鏈接
            for link in page.get_links():
                page.delete_link(link)
            # 替換圖片
            for img in page.get_images():
                page._insert_image(filename=file_list[index], _imgname=img[7])
                index = index + 1
        pdf.save(dest_pdf)
    finally:
        pdf.close()

三、實現(xiàn)效果

lu完代碼,再來看一下效果怎么樣,這邊用了兩個PDF做實驗,第一個PDF效果如下:

去除水印前:

在這里插入圖片描述

在這里插入圖片描述

去除水印后:

在這里插入圖片描述

在這里插入圖片描述

第二個PDF效果如下:

去除水印前:

在這里插入圖片描述

在這里插入圖片描述

去除水印后:

在這里插入圖片描述

在這里插入圖片描述

感覺效果還闊以,哈哈。不過這里有個問題,對于文字logo,查了PyMuPDF文檔沒找到罒ω罒,像這種

在這里插入圖片描述

四、代碼實現(xiàn)

全部代碼如下:

import os

import fitz
import numpy as np
from PIL import Image


def split_pdf(file_path, out_path):
    """
    切割pdf為圖片
    :param file_path: pdf路徑
    :param out_path: 輸出圖片路徑
    :return: 輸出路徑
    """
    pdf = fitz.open(file_path)
    count = 0
    print("##### 開始保存切割圖片 #####")
    for page in pdf:
        image_list = page.get_images()
        for img_info in image_list:
            pix = fitz.Pixmap(pdf, img_info[0])
            pix.save(os.path.join(out_path, '%d.jpg' % count))
            count += 1
    print("##### 保存切割圖片完畢 #####")
    print("##### {0} 包含 {1} 張圖片 #####".format(file_path, count))
    return out_path


def get_image_arr(img):
    """
    獲取圖片三色數(shù)組
    :param img:圖片
    :return: 圖片編碼、三色數(shù)組
    """
    img_arr = np.asarray(img, dtype=np.double)
    # 分離通道
    r_img = img_arr[:, :, 0].copy()
    g_img = img_arr[:, :, 1].copy()
    b_img = img_arr[:, :, 2].copy()
    img = r_img * 256 * 256 + g_img * 256 + b_img
    return img, r_img, g_img, b_img


def replace_clr_color(img, src_clr, dst_clr):
    """
    通過矩陣操作顏色替換程序
    @param  img:    圖像矩陣
    @param  src_clr:    需要替換的顏色(r,g,b)
    @param  dst_clr:    目標顏色        (r,g,b)
    @return             替換后的圖像矩陣
    """

    img, r_img, g_img, b_img = get_image_arr(img)
    src_color = src_clr[0] * 256 * 256 + src_clr[1] * 256 + src_clr[2]

    # 索引并替換顏色
    r_img[img == src_color] = dst_clr[0]
    g_img[img == src_color] = dst_clr[1]
    b_img[img == src_color] = dst_clr[2]

    return compound_img(r_img, g_img, b_img)


def compound_img(r_img, g_img, b_img):
    """
    合并圖片
    :param r_img: 紅色
    :param g_img: 綠色
    :param b_img: 藍色
    :return: 圖片
    """
    # 合并通道
    dst_img = np.array([r_img, g_img, b_img], dtype=np.uint8)
    # 將數(shù)據(jù)轉(zhuǎn)換為圖像數(shù)據(jù)(h,w,c)
    dst_img = dst_img.transpose(1, 2, 0)
    return dst_img


def replace_pure_color(img, src_color, dst_color):
    """
    通過矩陣操作顏色替換程序(純色)
    :param img: 圖像矩陣
    :param src_color: 需要替換的顏色
    :param dst_color: 目標顏色
    :return: 圖片
    """

    img, r_img, g_img, b_img = get_image_arr(img)
    src_color = src_color * 256 * 256 + src_color * 256 + src_color
    # 索引并替換顏色
    r_img[img >= src_color] = dst_color
    g_img[img >= src_color] = dst_color
    b_img[img >= src_color] = dst_color

    return compound_img(r_img, g_img, b_img)


def list_file(path, suffix=None):
    """
    獲取指定目錄下指定后綴文件
    :param path: 路徑
    :param suffix: 后綴名
    :return: 文件集合
    """
    file_names = os.listdir(path);
    # 獲取文件名
    if suffix is not None:
        file_names = [file_name for file_name in file_names if file_name.endswith(suffix)]
    file_names.sort(key=lambda x: int(x[:(-len(suffix))]))
    # 文件名拼接路徑
    return [os.path.join(path, file) for file in file_names]


def wipe_watermark(img_file, start_color):
    """
    去除圖片水印
    :param start_color: 顏色起始替換位置
    :param img_file: 圖片文件
    :return:
    """

    img = replace_pure_color(Image.open(img_file).convert('RGB'), start_color, 255)
    res_img = Image.fromarray(img)
    res_img.save(img_file)


def save_pdf(src_pdf, dest_pdf, file_list):
    """
    生成最終pdf文件
    :param src_pdf: 源文件
    :param dest_pdf: 目標文件
    :param file_list: 圖片列表
    :return:
    """
    pdf = fitz.open(src_pdf)
    index = 0
    try:
        for page in pdf:
            # 去除超鏈接
            for link in page.get_links():
                page.delete_link(link)
            # 替換圖片
            for img in page.get_images():
                page._insert_image(filename=file_list[index], _imgname=img[7])
                index = index + 1
        pdf.save(dest_pdf)
    finally:
        pdf.close()


def start(file_path, dest_path, start_color, out_path=r'out'):
    if os.path.exists(out_path):
        # shutil.rmtree(out_path)
        raise FileExistsError('文件夾:{0} 已存在'.format(out_path))
    os.mkdir(out_path)

    print("####### 開始切割pdf:{0} #######".format(file_path))
    split_pdf(file_path, out_path)
    print("####### 切割pdf完畢:{0} #######".format(file_path))
    # 獲取文件名
    file_list = list_file(out_path, ".jpg")

    print("####### 開始去除水印 #######")
    for img_file in file_list:
        wipe_watermark(img_file, start_color)
    print("####### 去除水印結(jié)束 #######")

    # 生成pdf
    print("####### 生成pdf文件:{0} #######".format(dest_path))
    save_pdf(src_pdf=file_path, dest_pdf=dest_path, file_list=file_list)
    print("####### 生成pdf文件:{0} 完成 #######".format(dest_path))
    # make_pdf(dest_path, file_list)


if __name__ == '__main__':
    # replace_pdf(src_pdf="深入剖析TOMCAT.pdf", dest_pdf='a.pdf', file_list=list_file('out', ".jpg"))
    # www.TopSage.com
    start(file_path="重構(gòu)-改善既有代碼的設(shè)計.pdf", dest_path="b.pdf", start_color=175)

總結(jié)

這里實現(xiàn)相對比較簡單,只能去除一些純色圖片的PDF。

以上就是使用python去除PDF簡單水印的示例的詳細內(nèi)容,更多關(guān)于python去除PDF水印的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 基于Python實現(xiàn)簡易的單詞記憶軟件

    基于Python實現(xiàn)簡易的單詞記憶軟件

    這篇文章主要為大家詳細介紹了如何基于Python實現(xiàn)一個簡易的單詞記憶軟件,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-07-07
  • Python數(shù)據(jù)庫sqlite3圖文實例詳解

    Python數(shù)據(jù)庫sqlite3圖文實例詳解

    SQLite是一個進程內(nèi)的庫,實現(xiàn)了自給自足的、無服務(wù)器的、零配置的、事務(wù)性的SQL數(shù)據(jù)庫引擎,下面這篇文章主要給大家介紹了關(guān)于Python數(shù)據(jù)庫sqlite3的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • Python之字典及while循環(huán)解讀

    Python之字典及while循環(huán)解讀

    這篇文章主要介紹了Python之字典及while循環(huán)解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Python使用sort()方法對數(shù)組進行排序的操作指南

    Python使用sort()方法對數(shù)組進行排序的操作指南

    在開發(fā)過程中,經(jīng)常需要對數(shù)據(jù)進行排序,Python 中的 sort() 方法是用來對列表進行排序的,它是一個非常常用且高效的排序工具,本文將通過一個實際項目的代碼示例,來講解如何使用 sort() 方法對數(shù)組進行排序,需要的朋友可以參考下
    2025-06-06
  • 從零開始學習Python Selenium瀏覽器元素定位與實戰(zhàn)技巧

    從零開始學習Python Selenium瀏覽器元素定位與實戰(zhàn)技巧

    這篇文章主要為大家詳細介紹了一份Selenium全教程,涵蓋從基礎(chǔ)到進階的核心知識點,基于Selenium 4版本(當前主流版本),適合新手入門及進階學習,快跟隨小編一起學習起來吧
    2026-03-03
  • python從子線程中獲得返回值的方法

    python從子線程中獲得返回值的方法

    今天小編就為大家分享一篇python從子線程中獲得返回值的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python基于Twilio及騰訊云實現(xiàn)國際國內(nèi)短信接口

    Python基于Twilio及騰訊云實現(xiàn)國際國內(nèi)短信接口

    這篇文章主要介紹了Python基于Twilio及騰訊云實現(xiàn)國際國內(nèi)短信接口,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-06-06
  • python用faker庫批量生成假數(shù)據(jù)

    python用faker庫批量生成假數(shù)據(jù)

    這篇文章主要介紹了python用faker庫批量生成假數(shù)據(jù),幫助大家更好的理解和學習使用python,感興趣的朋友可以了解下
    2021-03-03
  • Python設(shè)計模式中的結(jié)構(gòu)型橋接模式

    Python設(shè)計模式中的結(jié)構(gòu)型橋接模式

    這篇文章主要介紹了Python設(shè)計模式中的結(jié)構(gòu)型橋接模式,橋接模式即Bridge?Pattern,將抽象部分與它的實現(xiàn)部分分離,使它們都可以獨立地變化.下面來看看文章的詳細內(nèi)容介紹吧
    2022-02-02
  • Python實現(xiàn)合并兩個字典的8種方法

    Python實現(xiàn)合并兩個字典的8種方法

    Python有多種方法可以通過使用各種函數(shù)和構(gòu)造函數(shù)來合并字典,本文主要介紹了Python實現(xiàn)合并兩個字典的8種方法,具有一定的參考價值,感興趣的可以了解一下
    2024-07-07

最新評論

屯门区| 仙游县| 江永县| 昌黎县| 石城县| 仙桃市| 云安县| 偃师市| 新安县| 磐石市| 家居| 鄯善县| 宝清县| 卢龙县| 灵台县| 米泉市| 合山市| 芦溪县| 台南市| 眉山市| 博野县| 镇坪县| 民权县| 志丹县| 玉环县| 隆昌县| 红桥区| 莆田市| 田东县| 互助| 满洲里市| 平昌县| 旬阳县| 彰化市| 海淀区| 大同县| 长治市| 科技| 正蓝旗| 灯塔市| 长海县|