当前位置: 首页 > news >正文

通过分离有色和无色pdf页面减少打印费

前言

该工具是我认识的一位中科大的大佬在本科毕业的时候做的一个小工具,去打印店打印全彩的毕业论文的话会比较贵,他想到有没有一种方案可以实现有彩色页面的pdf和没有彩色页面的pdf分开打印,前者打印彩色,后者打印黑白,这样做的话可以节约很多打印彩色pdf页面的钱,然后这位大佬就做了这样一个小工具,省了一笔打印费,代码和原文链接在文末,我这里介绍下其大致的代码逻辑

1. is_color_image 函数

功能: 检查给定图像是否为彩色图像。

逻辑:

  • 将图像转换为 RGB 模式。
  • 将图像转换为 NumPy 数组,并归一化像素值到 [0,1] 范围。
  • 计算每个像素的最大和最小 RGB 值。
  • 计算每个像素的饱和度 (saturation)。
  • 统计饱和度大于阈值 (saturation_threshold) 的像素占总像素的比例 (color_fraction)。
  • 如果 color_fraction 大于设定的阈值 (color_fraction_threshold),则认为图像是彩色的。
def is_color_image(image, saturation_threshold=0.35, color_fraction_threshold=0.001):image = image.convert('RGB')pixels = np.array(image) / 255.0max_rgb = np.max(pixels, axis=2)min_rgb = np.min(pixels, axis=2)delta = max_rgb - min_rgbsaturation = delta / (max_rgb + 1e-7)  # 防止除以零color_pixels = saturation > saturation_thresholdcolor_fraction = np.mean(color_pixels)return color_fraction > color_fraction_threshold

2. is_color_page 函数

功能: 检查 PDF 页面是否为彩色页面。

逻辑:

  • 将页面渲染为 pixmap 对象。
  • 将 pixmap 转换为 PNG 格式的字节数据。
  • 使用 PIL 库将字节数据转换为图像对象。
  • 调用 is_color_image 函数检查图像是否为彩色图像。
def is_color_page(page):pix = page.get_pixmap()img = pix.tobytes("png")from PIL import Imagefrom io import BytesIOimage = Image.open(BytesIO(img))return is_color_image(image)

3. split_pdf 函数

功能: 将输入的 PDF 分割为彩色页面和黑白页面两个 PDF。

逻辑:

  • 打开输入 PDF。
  • 创建新的 PDF 对象来保存彩色页面和黑白页面。
  • 遍历输入 PDF 的每一页,检查页面是否为彩色页面。
  • 如果设置了双面打印 (is_double_sized_printing),确保彩色页面的前后页也包括在内。
  • 将彩色页面和黑白页面分别插入到新的 PDF 对象中。
  • 保存新的彩色和黑白 PDF。
  • 关闭所有文档对象。
def split_pdf(input_pdf_path, output_color_pdf_path, output_bw_pdf_path, is_double_sized_printing):doc = fitz.open(input_pdf_path)color_doc = fitz.open()bw_doc = fitz.open()color_pages = []bw_pages = []for page_num in tqdm(range(len(doc))):page = doc.load_page(page_num)if is_color_page(page):color_pages.append(page_num)if is_double_sized_printing:for page_num in color_pages:if page_num % 2 == 0 and page_num + 1 not in color_pages and page_num + 1 < len(doc):color_pages.append(page_num + 1)if page_num % 2 == 1 and page_num - 1 not in color_pages and page_num - 1 > 0:color_pages.append(page_num - 1)for page_num in range(len(doc)):if page_num not in color_pages:bw_pages.append(page_num)for page_num in sorted(color_pages):color_doc.insert_pdf(doc, from_page=page_num, to_page=page_num)for page_num in sorted(bw_pages):bw_doc.insert_pdf(doc, from_page=page_num, to_page=page_num)color_doc.save(output_color_pdf_path)bw_doc.save(output_bw_pdf_path)doc.close()color_doc.close()bw_doc.close()

主程序部分

功能: 定义输入、输出文件路径和是否双面打印的参数,并调用 split_pdf 函数。

if __name__ == '__main__':INPUT_PDF_PATH = '1.pdf'OUTPUT_COLOR_PDF_PATH = 'color_pages.pdf'OUTPUT_BW_PDF_PATH = 'bw_pages.pdf'IS_DOUBLE_SIZED_PRINTING = Truesplit_pdf(INPUT_PDF_PATH, OUTPUT_COLOR_PDF_PATH, OUTPUT_BW_PDF_PATH, IS_DOUBLE_SIZED_PRINTING)

完整代码

import pymupdf as fitz
import numpy as np
from tqdm import tqdmdef is_color_image(image, saturation_threshold=0.35, color_fraction_threshold=0.001):image = image.convert('RGB')pixels = np.array(image) / 255.0  # 归一化像素值到[0,1]范围# 将RGB转换为HSVmax_rgb = np.max(pixels, axis=2)min_rgb = np.min(pixels, axis=2)delta = max_rgb - min_rgb# 饱和度saturation = delta / (max_rgb + 1e-7)  # 防止除以零# 判断饱和度大于阈值的彩色像素color_pixels = saturation > saturation_thresholdcolor_fraction = np.mean(color_pixels)return color_fraction > color_fraction_thresholddef is_color_page(page):"""Check if a page is a color page."""# Render page to a pixmappix = page.get_pixmap()# Convert pixmap to an imageimg = pix.tobytes("png")# Create an image object using PILfrom PIL import Imagefrom io import BytesIOimage = Image.open(BytesIO(img))return is_color_image(image)def split_pdf(input_pdf_path, output_color_pdf_path, output_bw_pdf_path, is_double_sized_printing):# Open the input PDFdoc = fitz.open(input_pdf_path)# Create new PDFs for color and black & white pagescolor_doc = fitz.open()bw_doc = fitz.open()# Save color and bw pages numbercolor_pages = []bw_pages = []# Iterate over each page in the input PDFfor page_num in tqdm(range(len(doc))):page = doc.load_page(page_num)# Check if the page is a color pageif is_color_page(page):color_pages.append(page_num)# Handle double sized printingif is_double_sized_printing:for page_num in color_pages:if page_num % 2 == 0 and page_num + 1 not in color_pages and page_num + 1 < len(doc):color_pages.append(page_num + 1)if page_num % 2 == 1 and page_num - 1 not in color_pages and page_num - 1 > 0:color_pages.append(page_num - 1)# Insert BW Pagesfor page_num in range(len(doc)):if page_num not in color_pages:bw_pages.append(page_num)# Insert PDF pagesfor page_num in sorted(color_pages):color_doc.insert_pdf(doc, from_page=page_num, to_page=page_num)for page_num in sorted(bw_pages):bw_doc.insert_pdf(doc, from_page=page_num, to_page=page_num)# Save the new PDFscolor_doc.save(output_color_pdf_path)bw_doc.save(output_bw_pdf_path)# Close all documentsdoc.close()color_doc.close()bw_doc.close()if __name__ == '__main__':INPUT_PDF_PATH = '1.pdf'  # 待转换的PDF路径OUTPUT_COLOR_PDF_PATH = 'color_pages.pdf'  # 彩色部分PDF输出路径OUTPUT_BW_PDF_PATH = 'bw_pages.pdf'  # 黑白部分PDF输出路径IS_DOUBLE_SIZED_PRINTING = True  # 是否双面打印split_pdf(INPUT_PDF_PATH, OUTPUT_COLOR_PDF_PATH, OUTPUT_BW_PDF_PATH, IS_DOUBLE_SIZED_PRINTING)

原文链接:http://t.csdnimg.cn/VY0dE 

代码链接:https://github.com/RicePasteM/Color-BW-Separator-for-PDF.git

http://www.lryc.cn/news/385798.html

相关文章:

  • c语言--指针
  • python-九九乘法表(对齐式1)
  • thinkphp单独为某个接口设置缓存
  • OpenCV视觉--视频人脸微笑检测(超详细,附带检测资源)
  • docker 搭建 AI大数据模型 --- 使用GPU
  • 面向对象, 常用类, 集合, 异常, JDBC, mysql数据库 复习
  • js取数组最大值之Math.max、Math.max.apply
  • 各种中间件的安装
  • 【Mysql】多表查询、隐式内链接、显式内连接、左外连接、右外连接
  • Linux驱动开发(三)--新字符设备驱动开发 LED驱动开发升级
  • MCU的最佳存储方案CS创世 SD NAND
  • 40岁学习java是否需要报班学习?
  • Vitis Accelerated Libraries 学习笔记--OpenCV 运行测试
  • 加固三防平板如何提高轨道交通系统的运营效率?
  • Django 靓号管理系统:实现登录功能
  • 【Solr 学习笔记】Solr 源码启动教程
  • Java中的事件驱动编程模型
  • Python 语法基础一
  • 从零开始:Spring Boot 中使用 Drools 规则引擎的完整指南
  • 工业边缘计算网关
  • 【C++ 初阶路】--- 类和对象(末)
  • bable 【实用教程】
  • Android中使用startActivityForResult启动活动
  • NineData和华为云在一起!提供一站式智能数据库DevOps平台
  • 深入解析 Redisson分布式锁看门狗机制
  • Apache Arrow 和数据的未来:开放标准推动人工智能发展
  • Vue项目生产环境的打包优化
  • oracle数据库之使用Java程序调用存储过程(二十四)
  • 西电953总分第一、专业课第一考研上岸
  • pytorch-模型训练