You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PDF彩色页数统计代码优化求助:25页耗时近一分钟

优化思路与代码改进

你的代码效率低主要卡在两个核心环节:PDF转图像的过高分辨率设置,以及全图像像素的HSV转换与求和计算。以下是针对性的优化方案:

1. 降低PDF转图像的分辨率

当前设置的500dpi分辨率对于“判断页面是否为彩色”的需求完全过剩。将分辨率降至100dpi甚至更低,能大幅减少单页图像的像素总量,直接缩短转换和后续处理的时间。

修改后的转换代码:

images = convert_from_path("example1.pdf", 100, poppler_path=r'C:\Program Files\poppler-0.68.0\bin')

2. 简化彩色判断逻辑,避免全像素遍历

原代码的HSV求和逻辑需要遍历所有像素并进行颜色空间转换,冗余且低效。可以通过以下方式简化:

  • 先将图像缩小到极小尺寸(比如10x10),大幅减少需要检查的像素数
  • 在RGB空间直接判断:若存在任意像素的R/G/B值差异超过微小阈值(处理压缩噪声),则判定为彩色

示例代码:

from pdf2image import convert_from_path

def is_color_page(image):
    # 缩小图像到10x10,减少计算量
    small_img = image.resize((10, 10))
    pixels = small_img.getdata()
    for r, g, b in pixels:
        # 允许微小差异,避免压缩导致的伪彩色误判
        if abs(r - g) > 3 or abs(r - b) > 3 or abs(g - b) > 3:
            return True
    return False

def main():
    images = convert_from_path("example1.pdf", 100, poppler_path=r'C:\Program Files\poppler-0.68.0\bin')
    sw = 0
    color = 0
    for image in images:
        if is_color_page(image):
            color += 1
        else:
            sw += 1
    print(f"彩色页数: {color}")
    print(f"黑白页数: {sw}")

if __name__ == "__main__":
    main()

3. 直接调用Poppler命令行工具(跳过Python图像转换)

如果仅需统计彩色页数,可以直接用Poppler的命令行工具完成判断,完全跳过Python层面的图像处理,这是效率最高的方案。核心思路是对比原页面与灰度页面的文件大小差异,差异显著则为彩色。

示例代码:

import subprocess

def count_color_pages(pdf_path, poppler_bin_path):
    # 获取总页数
    pdfinfo_output = subprocess.check_output([f"{poppler_bin_path}/pdfinfo.exe", pdf_path]).decode()
    total_pages = int([line for line in pdfinfo_output.split('\n') if 'Pages:' in line][0].split(':')[1].strip())
    
    color_count = 0
    for page in range(1, total_pages + 1):
        # 生成原页10px缩略图的字节数据
        orig_cmd = [
            f"{poppler_bin_path}/pdftoppm.exe",
            "-f", str(page), "-l", str(page),
            "-scale-to", "10", "-jpeg", "-tempfile",
            pdf_path
        ]
        orig_size = len(subprocess.check_output(orig_cmd))
        
        # 生成灰度页10px缩略图的字节数据
        gray_cmd = [
            f"{poppler_bin_path}/pdftoppm.exe",
            "-f", str(page), "-l", str(page),
            "-scale-to", "10", "-gray", "-jpeg", "-tempfile",
            pdf_path
        ]
        gray_size = len(subprocess.check_output(gray_cmd))
        
        # 大小差异超过阈值则判定为彩色
        if abs(orig_size - gray_size) > 100:
            color_count += 1
    return color_count, total_pages - color_count

def main():
    poppler_path = r'C:\Program Files\poppler-0.68.0\bin'
    color, sw = count_color_pages("example1.pdf", poppler_path)
    print(f"彩色页数: {color}")
    print(f"黑白页数: {sw}")

if __name__ == "__main__":
    main()

4. 并行处理多页任务

利用CPU多核心,通过线程池并行处理多页的转换与判断,进一步缩短总耗时。

示例代码:

from pdf2image import convert_from_path
from concurrent.futures import ThreadPoolExecutor

def is_color_page(image):
    small_img = image.resize((10, 10))
    pixels = small_img.getdata()
    for r, g, b in pixels:
        if abs(r - g) > 3 or abs(r - b) > 3 or abs(g - b) > 3:
            return True
    return False

def main():
    images = convert_from_path("example1.pdf", 100, poppler_path=r'C:\Program Files\poppler-0.68.0\bin')
    with ThreadPoolExecutor() as executor:
        results = list(executor.map(is_color_page, images))
    color = sum(results)
    sw = len(results) - color
    print(f"彩色页数: {color}")
    print(f"黑白页数: {sw}")

if __name__ == "__main__":
    main()

内容的提问来源于stack exchange,提问作者JavaNoob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 00:45:36