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

使用PyMuPDF提取PDF图片遇异常:漏图、尺寸异常及偏色求助

解决PDF图片提取缺失、尺寸异常及颜色偏暗问题

问题描述

使用以下基于fitz(PyMuPDF)的Python代码提取PDF图片时,出现部分图片缺失、部分提取出的图片尺寸为1×1的情况,此前尝试提取时还存在图片颜色偏暗的问题,需要实现原样提取PDF中的所有图片。

原代码:

import fitz

# Open the PDF file
file = fitz.open("D41813 LS K2W COLLAR TOP 000751556 (0318).pdf")

# Iterate through each page of the PDF
for pageNumber, page in enumerate(file, start=1):
    # Get the list of images on the current page
    for imgNumber, img in enumerate(page.get_images(full=True), start=1):
        xref = img[0]

        # Extract the image
        pix = fitz.Pixmap(file, xref)

        # Convert the image to RGB if it is not already in that format
        if pix.n > 4 or pix.alpha:  # Check if the image is CMYK or has alpha channel
            pix = fitz.Pixmap(fitz.csRGB, pix)

        # Save the image with a unique filename
        pix.save(f"page{pageNumber}_img{imgNumber}.jpg")

# Close the PDF file
file.close()

解决方案

1. 过滤1×1尺寸的占位图片

PDF中这类极小图片多为内部标记或透明占位元素,直接过滤即可:

# 在提取Pixmap后添加尺寸判断
if pix.width <= 1 and pix.height <= 1:
    continue  # 跳过无效占位图

2. 修复颜色偏暗问题

CMYK转RGB时默认转换逻辑易出现色彩偏差,优先保留原图格式可避免损失:

# 获取图片原始格式(从PDF图片元数据中提取)
img_ext = img[1].split(".")[-1].lower() if len(img[1]) > 0 else "png"

# 仅在目标格式为JPG且需要色彩转换时处理
if img_ext in ("jpg", "jpeg") and (pix.n > 4 or pix.alpha):
    pix = fitz.Pixmap(fitz.csRGB, pix)
    pix.save(f"page{pageNumber}_img{imgNumber}.jpg")
else:
    # 保存为原始格式(如PNG),最大程度保留色彩信息
    pix.save(f"page{pageNumber}_img{imgNumber}.{img_ext}")

3. 提取所有嵌入式图片(含页面未直接引用的)

部分图片存储在PDF资源中但未被页面显式引用,遍历所有xref对象可补全提取:

# 遍历PDF所有对象,提取图片类型资源
for xref in range(1, file.xref_length()):
    # 判断当前对象是否为图片
    if file.xref_get_key(xref, "Subtype")[1] == "/Image":
        pix = fitz.Pixmap(file, xref)
        if pix.width <= 1 and pix.height <= 1:
            continue
        # 色彩转换与保存逻辑同前
        if pix.n > 4 or pix.alpha:
            pix = fitz.Pixmap(fitz.csRGB, pix)
        pix.save(f"image_xref{xref}.jpg")

完整优化代码

import fitz

def extract_pdf_images(pdf_path):
    file = fitz.open(pdf_path)
    
    # 提取页面可见图片
    for page_num, page in enumerate(file, start=1):
        for img_num, img in enumerate(page.get_images(full=True), start=1):
            xref = img[0]
            pix = fitz.Pixmap(file, xref)
            
            # 跳过极小占位图
            if pix.width <= 1 and pix.height <= 1:
                continue
            
            # 获取原始图片格式
            img_ext = img[1].split(".")[-1].lower() if img[1] else "png"
            
            # 处理色彩空间并保存
            if (pix.n > 4 or pix.alpha) and img_ext in ("jpg", "jpeg"):
                pix = fitz.Pixmap(fitz.csRGB, pix)
                pix.save(f"page{page_num}_img{img_num}.jpg")
            else:
                pix.save(f"page{page_num}_img{img_num}.{img_ext}")
            
            # 释放资源
            if pix.n > 0:
                pix = None
    
    # 提取所有嵌入式图片(补充页面未引用的)
    for xref in range(1, file.xref_length()):
        if file.xref_get_key(xref, "Subtype")[1] == "/Image":
            pix = fitz.Pixmap(file, xref)
            if pix.width <= 1 and pix.height <= 1:
                continue
            if pix.n > 4 or pix.alpha:
                pix = fitz.Pixmap(fitz.csRGB, pix)
            pix.save(f"image_xref{xref}.jpg")
            if pix.n > 0:
                pix = None
    
    file.close()

# 调用提取函数
extract_pdf_images("D41813 LS K2W COLLAR TOP 000751556 (0318).pdf")

关键说明

  • 极小尺寸图片属于PDF内部冗余元素,过滤后不影响真实内容提取。
  • 保留原始图片格式是避免色彩偏差的核心,仅在需要JPG格式时才进行CMYK转RGB。
  • 遍历所有xref对象可覆盖页面未显式引用的嵌入式图片,解决缺失问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:13:16