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

一款基于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 Imagedef 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 osdef extract_pdf_images(file_path, output_dir):doc = fitz.open(file_path)img_count = 0for 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"]# 保存为PNGimg_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 += 1return img_count

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

from openpyxl import load_workbook
import osdef extract_excel_images(file_path, output_dir):wb = load_workbook(file_path)img_count = 0for sheet in wb.worksheets:for image in sheet._images:# 获取图片数据img = image._dataimg_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 += 1return img_count

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

import requests
from bs4 import BeautifulSoup
import os
import base64def 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 = 0for 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 += 1return 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 osclass ImageExtractorApp:def __init__(self, root):self.root = rootself.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("错误", "不支持的文件类型")returnself.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.rhkb.cn/news/34895.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

日志存储与分析

日志是系统运行的详细记录,包含各种事件发生的主体、时间、位置、内容等关键信息。出于运维可观测、网络安全监控及业务分析等多重需求,企业通常需要将分散的日志采集起来,进行集中存储、查询和分析,以进一步从日志数据里挖掘出有…

cyberstrikelab lab2

lab2 重生之我是渗透测试工程师,被公司派遣去测试某网络的安全性。你的目标是成功获取所有服务器的权限,以评估网络安全状况。 先扫一下 ​ ​ 192.168.10.10 ​ ​ 骑士cms 先找后台路径 http://192.168.10.10:808/index.php?madmin&cind…

1.5.2 掌握Scala内建控制结构 - 块表达式

Scala的块表达式使用{}包裹语句组,单行语句不加分号,多语句用分号隔开。块表达式的结果是最后一行语句的值,无需单独写return。若无执行结果,则返回Unit对象(类似Java的void)。例如,有返回值时&…

VSCode + CMake

参考文献: 如何用 GCC, CMake 和 Make 编译C/C代码Windows 上的 Linux 子系统:WSLWSL:桌面 UI 远程连接 RDP 配置 VScode 文章目录 CMake 配置VSCode 配置launch.jsontask.jsonc_cpp_properties.json CMake 配置 编写如下的 CmakeLists.t…

【软考-架构】7、系统配置与性能评价

✨资料&文章更新✨ GitHub地址:https://github.com/tyronczt/system_architect 文章目录 性能指标💯考试真题第一题第二题 性能评价方法💯考试真题第一题第二题 阿姆达尔解决方法考试真题 性能指标 对计算机评价的主要性能指标有&#x…

STC89C52单片机学习——第20节: [8-2]串口向电脑发送数据电脑通过串口控制LED

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.03.15 51单片机学习——第20节: [8-2]串口向电脑发送数据&电脑通过串口控制LED 前言…

java简单基础学习

目录 简单5位验证码快捷键的使用 评委打分5个评委 去掉一个最高分和一个最低分 取平均分 抢红包出现数组越界java​编辑 双色球系统--之蒟蒻学习 简单5位验证码快捷键的使用 题目意思做个验证码 //生成一个5位数的验证码 //前四位是字母,大小字母都可以 //最后一位要是数字…

前端学习记录:解决路由缓存问题

问题描述:响应路由参数的变化,使用带有参数的路由时需要注意的是,当用户从 /users/johnoy 导航到 /users/jolyne 时,相同的组件实例将会被重复使用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得…

Leetcode-1278.Palindrome Partitioning III [C++][Java]

目录 一、题目描述 二、解题思路 【C】 【Java】 Leetcode-1278.Palindrome Partitioning IIIhttps://leetcode.com/problems/palindrome-partitioning-iii/description/1278. 分割回文串 III - 力扣(LeetCode)1278. 分割回文串 III - 给你一个由小写…

deepseek GRPO算法保姆级讲解(数学原理+源码解析+案例实战)

文章目录 什么是GRPO群组形成(Group Formation):让大模型创建多种解决方案偏好学习(Preference Learning):让大模型理解何为好的解答组内相对优势 优化(optimization): 让大模型从经验中学习(learning from experience)目标函数 GRPO算法的伪码表示GRPO算法的局限与…

【Linux我做主】基础命令完全指南上篇

Linux基础命令完全指南【上篇】 Linux基础命令完全指南github地址前言命令行操作的引入Linux文件系统树形结构的根文件系统绝对路径和相对路径适用场景Linux目录下的隐藏文件 基本指令目录和文件相关1. ls2. cd和pwdcdpwd 3. touch4. mkdir5. cp6. mv移动目录时覆盖写入的两种特…

自然语言秒转SQL—— 免费体验 OB Cloud Text2SQL 数据查询

在数据驱动决策的今天,企业急需从庞大业务数据中提炼信息,获取深度洞察。然而,面对海量数据,业务人员往往因缺乏SQL专业技能而难以快速查询和分析所需信息,频繁求助于BI部门不仅抬高了企业的沟通与时间成本&#xff0c…

鸿蒙next 多行文字加图片后缀实现方案

需求 实现类似iOS的YYLabel之类的在文字后面加上图片作为后缀的样式,多行时文字使用…省略超出部分,但必须保证图片的展现。 系统方案 在当前鸿蒙next系统提供的文字排版方法基本没有合适使用的接口,包括imagespan和RichEditor,根据AI的回…

C语言基础知识04---指针

目录 1、指针 1.1 指针概念 1.2 指针的大小 1.3 指针的定义 1.4 多级指针 1.5 指针的初始化 1.6 指针的使用 1.7 类型转换 1.8 大小端 1.9 地址偏移 1.10 指针常量&&常量指针 1.11 指针数组&&数组指针 1、指针 1.1 指针概念 指针保存地址&#xff…

spring boot 发送邮件验证码

一、前置需求 1、准备邮箱 2、登录授权码 qq邮箱在–>设置–>账号POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 开启服务 二、发送邮件 1、简单邮件 包含邮件标题、邮件正文 2、引入mail启动器 <dependency><groupId>org.springframework.boot</groupI…

Spring Cloud Config - 动态配置管理与高可用治理

引言&#xff1a;为什么需要配置中心&#xff1f; 在微服务架构中&#xff0c;配置管理面临分散化、多环境、动态更新三大挑战。传统基于application.yml等配置文件的硬编码方式&#xff0c;导致以下问题&#xff1a; • 环境差异&#xff1a;开发、测试、生产环境配置混杂&a…

[网络][tcp协议]:tcp报头

tcp(传输控制协议)是一种面向字节流的传输层协议,相较于udp协议,tcp能保证传输数据的可靠性与准确性,tcp也是目前最常见的传输层协议 本文主要介绍tcp报头各个字段的含义与用途 注:保留6位和6位标记位是目前最普遍的写法,在我查资料时,发现有一些拓展情况,会在后文细说 最简单的…

【sklearn 01】人工智能概述

一、人工智能&#xff0c;机器学习&#xff0c;深度学习 人工智能指由人类制造出的具有智能的机器。这是一个非常大的范围&#xff0c;长远目标是让机器实现人工智能&#xff0c;但目前我们仍处在非常初始的阶段&#xff0c;甚至不能称为智能 机器学习是指通过数据训练出能完成…

Excel ScriptLab学习笔记

注意 The Excel JavaScript API 没有“Cell”对象或类。 相反&#xff0c;Excel JavaScript API 将所有 Excel 单元格定义为 Range 对象。 Excel UI 中的单个单元格转换为 Excel JavaScript API 中包含一个单元格的 Range 对象。 单个 Range 对象也可以包含多个连续的单元格。…

【数据结构】线性表简介

0.本篇问题 线性表&#xff0c;顺序表&#xff0c;链表什么关系&#xff1f;它们是逻辑结构还是存储结构&#xff1f;线性表的基本操作有哪些&#xff1f; 线性表是具有相同数据元素的有限序列。 表中元素有先后次序&#xff0c;每个元素占有相同大小的存储空间。 一、线性…