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
相关产品推荐
相关产品推荐

