一款基于Python的从常规文档里提取图片的简单工具开发方案

news2025/3/17 15:08:28

一款基于Python的从常规文档里提取图片的简单工具开发方案


在这里插入图片描述

1. 环境准备

安装必需库

pip install python-docx PyMuPDF openpyxl beautifulsoup4 pillow
pip install pdfplumber  # PDF解析备用方案
pip install tk          # Python自带,无需安装

工具选择

  • 开发环境:VSCode + Python插件
  • 调试工具:Python IDLE(初学者友好)
  • 打包工具:pyinstaller(可选,用于生成exe)

2. 项目架构设计

image-extractor/
├── main.py            # 主程序入口
├── core/
│   ├── docx_extractor.py
│   ├── pdf_extractor.py
│   ├── excel_extractor.py
│   └── html_extractor.py
└── outputs/           # 默认输出目录

3. 核心功能实现

(1) Word文档提取 (docx_extractor.py)

import zipfile
import os
from PIL import Image

def extract_docx_images(file_path, output_dir):
    # 解压docx文件
    with zipfile.ZipFile(file_path, 'r') as zip_ref:
        # 提取media文件夹内的图片
        image_files = [f for f in zip_ref.namelist() if f.startswith('word/media/')]
        
        for img_file in image_files:
            # 保存图片到输出目录
            zip_ref.extract(img_file, output_dir)
            # 重命名文件
            src = os.path.join(output_dir, img_file)
            dst = os.path.join(output_dir, os.path.basename(img_file))
            os.rename(src, dst)
            
    return len(image_files)

(2) PDF文件提取 (pdf_extractor.py)

import fitz  # PyMuPDF
import os

def extract_pdf_images(file_path, output_dir):
    doc = fitz.open(file_path)
    img_count = 0
    
    for page_num in range(len(doc)):
        page = doc.load_page(page_num)
        images = page.get_images(full=True)
        
        for img_index, img in enumerate(images):
            xref = img[0]
            base_image = doc.extract_image(xref)
            img_data = base_image["image"]
            
            # 保存为PNG
            img_path = os.path.join(output_dir, f"pdf_page{page_num}_img{img_index}.png")
            with open(img_path, "wb") as f:
                f.write(img_data)
            img_count += 1
                
    return img_count

(3) Excel文件提取 (excel_extractor.py)

from openpyxl import load_workbook
import os

def extract_excel_images(file_path, output_dir):
    wb = load_workbook(file_path)
    img_count = 0
    
    for sheet in wb.worksheets:
        for image in sheet._images:
            # 获取图片数据
            img = image._data
            img_path = os.path.join(output_dir, f"excel_{sheet.title}_img{img_count}.png")
            with open(img_path, "wb") as f:
                f.write(img)
            img_count += 1
                
    return img_count

(4) HTML文件提取 (html_extractor.py)

import requests
from bs4 import BeautifulSoup
import os
import base64

def extract_html_images(html_path, output_dir):
    if html_path.startswith('http'):
        response = requests.get(html_path)
        soup = BeautifulSoup(response.text, 'html.parser')
    else:
        with open(html_path, 'r') as f:
            soup = BeautifulSoup(f.read(), 'html.parser')
    
    img_tags = soup.find_all('img')
    img_count = 0
    
    for img in img_tags:
        src = img.get('src')
        if src.startswith('data:image'):
            # 处理base64编码图片
            header, data = src.split(',', 1)
            img_format = header.split('/')[1].split(';')[0]
            img_data = base64.b64decode(data)
            img_path = os.path.join(output_dir, f"html_img{img_count}.{img_format}")
            with open(img_path, 'wb') as f:
                f.write(img_data)
            img_count += 1
                
    return img_count

4. 交互界面开发 (main.py)

import tkinter as tk
from tkinter import filedialog, messagebox
from core import docx_extractor, pdf_extractor, excel_extractor, html_extractor
import os

class ImageExtractorApp:
    def __init__(self, root):
        self.root = root
        self.root.title("多格式图片提取工具")
        
        # 文件路径变量
        self.file_path = tk.StringVar()
        self.output_dir = tk.StringVar(value="outputs")
        
        # 创建界面组件
        self.create_widgets()
    
    def create_widgets(self):
        # 文件选择
        tk.Label(self.root, text="选择文件:").grid(row=0, column=0, padx=5, pady=5)
        tk.Entry(self.root, textvariable=self.file_path, width=40).grid(row=0, column=1)
        tk.Button(self.root, text="浏览", command=self.select_file).grid(row=0, column=2)
        
        # 输出目录
        tk.Label(self.root, text="输出目录:").grid(row=1, column=0)
        tk.Entry(self.root, textvariable=self.output_dir, width=40).grid(row=1, column=1)
        tk.Button(self.root, text="选择目录", command=self.select_output_dir).grid(row=1, column=2)
        
        # 执行按钮
        tk.Button(self.root, text="开始提取", command=self.start_extraction).grid(row=2, column=1, pady=10)
        
        # 日志区域
        self.log_text = tk.Text(self.root, height=10, width=50)
        self.log_text.grid(row=3, column=0, columnspan=3)
    
    def select_file(self):
        file_types = [
            ('支持的文件类型', '*.docx *.pdf *.xlsx *.html'),
            ('Word文档', '*.docx'),
            ('PDF文件', '*.pdf'),
            ('Excel文件', '*.xlsx'),
            ('网页文件', '*.html')
        ]
        self.file_path.set(filedialog.askopenfilename(filetypes=file_types))
    
    def select_output_dir(self):
        self.output_dir.set(filedialog.askdirectory())
    
    def start_extraction(self):
        file_path = self.file_path.get()
        output_dir = self.output_dir.get()
        
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)
            
        ext = os.path.splitext(file_path)[1].lower()
        
        try:
            if ext == '.docx':
                count = docx_extractor.extract_docx_images(file_path, output_dir)
            elif ext == '.pdf':
                count = pdf_extractor.extract_pdf_images(file_path, output_dir)
            elif ext == '.xlsx':
                count = excel_extractor.extract_excel_images(file_path, output_dir)
            elif ext == '.html':
                count = html_extractor.extract_html_images(file_path, output_dir)
            else:
                messagebox.showerror("错误", "不支持的文件类型")
                return
                
            self.log_text.insert(tk.END, f"成功提取 {count} 张图片到 {output_dir}\n")
        except Exception as e:
            messagebox.showerror("错误", f"提取失败: {str(e)}")

if __name__ == "__main__":
    root = tk.Tk()
    app = ImageExtractorApp(root)
    root.mainloop()

5. 使用说明

操作步骤

  1. 运行 main.py
  2. 点击 浏览 选择文件 (支持.docx/.pdf/.xlsx/.html)
  3. 选择输出目录(默认 outputs)
  4. 点击 开始提取
  5. 查看底部日志区域的提取结果

效果示例

成功提取 5 张图片到 outputs/
成功提取 3 张图片到 outputs/

6. 常见问题解决

Q1: Excel图片无法提取?

  • 原因:openpyxl只能提取嵌入式图片,无法提取浮动图片
  • 解决方案:改用xlrd+图像坐标识别(需更复杂处理)

Q2: PDF提取的图片模糊?

  • 原因:PDF内嵌低分辨率图片
  • 解决方案:使用pdfplumber的更高精度提取模式

Q3: 程序无响应?

  • 原因:大文件处理耗时阻塞主线程
  • 解决方案:改用多线程处理(参考threading模块)

7. 项目扩展建议

  1. 增加批量处理:支持文件夹批量导入
  2. 添加图片预览:在界面中显示缩略图
  3. 支持压缩包:直接解压ZIP/RAR文件并处理内容
  4. 增加格式转换:自动转换HEIC/WEBP等特殊格式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2316684.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JetBrains(全家桶: IDEA、WebStorm、GoLand、PyCharm) 2024.3+ 2025 版免费体验方案

JetBrains(全家桶: IDEA、WebStorm、GoLand、PyCharm) 2024.3 2025 版免费体验方案 前言 JetBrains IDE 是许多开发者的主力工具,但从 2024.02 版本起,JetBrains 调整了试用政策,新用户不再享有默认的 30 天免费试用…

Docker生存手册:安装到服务一本通

文章目录 一. Docker 容器介绍1.1 什么是Docker容器?1.2 为什么需要Docker容器?1.3 Docker架构1.4 Docker 相关概念1.5 Docker特点 二. Docker 安装2.1 查看Linux内核版本2.2 卸载老版本docker,避免产生影响2.3 升级yum 和配置源2.4 安装Dock…

Linux内核传输层UDP源码分析

一、用户数据包协议(UDP) 1.UDP数据报头 UDP 提供面向消息的不可靠传输,但没有拥塞控制功能。很多协议都使用 UDP,如用于 IP 网络传输音频和视频的实时传输协议 (Real-time Transport Protocol,RTP),此类型…

FPGA学习(二)——实现LED流水灯

FPGA学习(二)——实现LED流水灯 目录 FPGA学习(二)——实现LED流水灯一、DE2-115时钟源二、控制6个LED灯实现流水灯1、核心逻辑2、代码实现3、引脚配置4、实现效果 三、模块化代码1、分频模块2、复位暂停模块3、顶层模块 四、总结 一、DE2-115时钟源 DE2-115板子包含一个50MHz…

Linux如何在设备树中表示和引用设备信息

DTS基本知识 dts 硬件的相应信息都会写在.dts为后缀的文件中,每一款硬件可以单独写一份xxxx.dts,一般在Linux源码中存在大量的dts文件,对于arm架构可以在arch/arm/boot/dts找到相应的dts,一个dts文件对应一个ARM的machie。 dtsi 值…

Matlab 汽车振动多自由度非线性悬挂系统和参数研究

1、内容简介 略 Matlab 169-汽车振动多自由度非线性悬挂系统和参数研究 可以交流、咨询、答疑 2、内容说明 略 第二章 汽车模型建立 2.1 汽车悬架系统概述 2.1.1 悬架系统的结构和功能 2.1.2 悬架分类 2.2 四分之一车辆模型 对于车辆动力学,一般都是研究其悬…

生活中的可靠性小案例11:窗户把手断裂

窗户把手又断了,之前也断过一次,使用次数并没有特别多。上方的图是正常的把手状态,断的形状如下方图所示。 这种悬臂梁结构,没有一个良好的圆角过渡,导致应力集中。窗户的开关,对应的是把手的推拉&#xff…

[oeasy]python074_ai辅助编程_水果程序_fruits_apple_banana_加法_python之禅

074_ai辅助编程_水果程序_fruits_加法 回忆上次内容 上次直接从模块中导入变量、函数 from my_file import pi 导入my_file.pi 并作为 pi 使用 from my_file import pi as my_pi 导入变量 并 重命名 添加图片注释,不超过 140 字(可选) …

【图论】并查集的学习和使用

目录 并查集是什么? 举个例子 组成 父亲数组: find函数: union函数: 代码实现: fa[] 初始化code: find code: 递归实现: 非递归实现: union code : 画图模拟: 路径压缩&#xff1a…

欢乐力扣:反转链表

文章目录 1、题目描述2、思路 1、题目描述 反转链表。  给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 2、思路 借助cur指针和pre双指针来调整链表的前后指向。 # Definition for singly-linked list. # class ListNode: # def __i…

什么是大带宽服务器

什么是大带宽服务器? 在深入探讨大带宽之前,让我们先明确带宽的概念。带宽与我们日常所说的宽带有所不同,宽带是运营商为满足家庭或商业上网需求所提供的服务,而带宽则特指数据的传输速度,尤其是上行速度。大带宽服务…

【TCP】三次挥手,四次挥手详解--UDP和TCP协议详解

活动发起人小虚竹 想对你说: 这是一个以写作博客为目的的创作活动,旨在鼓励大学生博主们挖掘自己的创作潜能,展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴,那么,快来参加吧&#xff01…

SSM基础专项复习4——Maven项目管理工具(1)

系列文章 1、SSM基础专项复习1——SSM项目整合-CSDN博客 2、SSM基础专项复习2——Spring 框架(1)-CSDN博客 3、SSM基础专项复习3——Spring框架(2)-CSDN博客 文章目录 系列文章 1. Maven 的概念 1.1. 什么是 Maven 1.2. 什…

使用c#进行串口通信

一、串口通信协议 1.串口通信协议简介 串口通信(serial communication)是一种设备间非常常用的串行通信方式,大部分电子设备都支持,电子工程师再调试设备时也经常使用该通信方式输出调试信息。讲到某一种通信协议,离…

Web开发-PHP应用鉴别修复AI算法流量检测PHP.INI通用过滤内置函数

知识点: 1、安全开发-原生PHP-PHP.INI安全 2、安全开发-原生PHP-全局文件&单函数 3、安全开发-原生PHP-流量检测&AI算法 一、演示案例-WEB开发-修复方案-PHP.INI配置 文章参考: https://www.yisu.com/ask/28100386.html https://blog.csdn.net/…

蓝桥模拟+真题讲解

今天谁一篇文章哈 ! 由于本篇文章有些的题目只有图片,因此还望各位见谅。 目录 第一题 题目解析 代码原理 代码编写 填空技巧---巧用python 第二题 题目解析 ​编辑 填空技巧---巧用python 第三题 题目链接 题目解析 必备知识 解题技巧 …

C语言【数据结构】:时间复杂度和空间复杂度.详解

引言 详细介绍什么是时间复杂度和空间复杂度。 前言:为什么要学习时间复杂度和空间复杂度 算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源。因此衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的,即时…

基于Python的selenium入门超详细教程(第2章)--单元测试框架unittest

学习路线 自动化测试介绍及学习路线-CSDN博客 ​自动化测试之Web自动化(基于pythonselenium)-CSDN博客 基于Python的selenium入门超详细教程(第1章)--WebDriver API篇-CSDN博客 目录 前言: 一、单元测试 1. 单元测试的定义 2. 单元测…

日志、类加载器、XML(配置文件)

目录 一、日志1.日志技术的概述2.日志技术的体系a. Logback 3.日志的级别 二、类加载器1.概述2.类加载时机3.类加载过程3.类加载器的分类4.常用方法 三、XML(配置文件)1.概述2.XML的基本语法3.XML的文档约束a.DTD约束b.schema约束 4.XML文档解析a.Dom4jb…

AI大白话(一):5分钟了解AI到底是什么?

🌟引言: 在这个信息爆炸的时代,“人工智能”、“AI”、“机器学习”、"深度学习"等词汇频繁出现在我们的生活中。 从手机里的语音助手,到网购平台的个性化推荐,再到最近大火的AI绘画和ChatGPT,人…