当前位置: 首页 > wzjs >正文

合肥网站建设推荐 晨飞网络计算机编程培训学校哪家好

合肥网站建设推荐 晨飞网络,计算机编程培训学校哪家好,ps做网站界面,怎么用手机做网站编辑前几天完成《 AI 时代,如何用 Python 脚本轻松搞定 PDF 需求?》,有朋友反馈使用到 poppler 这个工具还是有点麻烦,能不能就安装 python 库就可以解决,我让 AI 根据需求,重写了一版本,包括处理 P…

前几天完成《 AI 时代,如何用 Python 脚本轻松搞定 PDF 需求?》,有朋友反馈使用到 poppler 这个工具还是有点麻烦,能不能就安装 python 库就可以解决,我让 AI 根据需求,重写了一版本,包括处理 PDF 页面、合并 PDF、提取图片、加密和解密 PDF 文件。 

图片

依赖库

要使用这个工具,您需要安装以下 Python 库: 

PyMuPDF (fitz) 

Pillow (PIL) 

您可以使用以下命令安装这些库: 

pip install PyMuPDF Pillow

 

功能概述

  • 处理 PDF:选择特定页面并转换为图片或新的 PDF
  • 合并 PDF:将多个 PDF 文件合并为一个
  • 提取图片:从 PDF 中提取图片
  • 加密 PDF:为 PDF 文件添加密码保护
  • 解密 PDF:移除 PDF 文件的密码保护

 

代码

import argparse
import os
import fitz  # PyMuPDF
import io
from PIL import Imagedef try_remove_pdf_password(input_path, password=None):doc = fitz.open(input_path)if doc.is_encrypted:if password is None:# 尝试无密码解密if doc.authenticate(""):print("PDF文件已成功解密(无需密码)")return input_pathelse:raise ValueError("PDF文件已加密,需要密码")else:if doc.authenticate(password):output_path = input_path.replace('.pdf', '_decrypted.pdf')doc.save(output_path)print(f"已解密的PDF保存到: {output_path}")return output_pathelse:raise ValueError("提供的密码不正确")else:print("PDF文件未加密")return input_pathdef parse_page_ranges(page_range, total_pages):if not page_range:return list(range(1, total_pages + 1))  # 如果没有指定页码,返回所有页面pages = set()ranges = page_range.split(',')for r in ranges:if '-' in r:start, end = map(int, r.split('-'))pages.update(range(start, min(end + 1, total_pages + 1)))else:page = int(r)if 1 <= page <= total_pages:pages.add(page)return sorted(list(pages))def process_pdf(input_path, page_range, output_path, dpi=300, split_pages=False, password=None):doc = fitz.open(input_path)if doc.is_encrypted:if not doc.authenticate(password):raise ValueError("密码不正确")total_pages = len(doc)pages_to_process = parse_page_ranges(page_range, total_pages)_, file_extension = os.path.splitext(output_path)output_format = file_extension[1:].lower()if output_format in ['jpg', 'jpeg', 'png']:zoom = dpi / 72  # 默认 DPI 为 72mat = fitz.Matrix(zoom, zoom)if split_pages:base_name, ext = os.path.splitext(output_path)for page_num in pages_to_process:page = doc[page_num - 1]pix = page.get_pixmap(matrix=mat, alpha=False)img = Image.open(io.BytesIO(pix.tobytes()))page_output_path = f"{base_name}_{page_num}{ext}"img.save(page_output_path)print(f"输出文件已保存到: {page_output_path}")else:images = []for page_num in pages_to_process:page = doc[page_num - 1]pix = page.get_pixmap(matrix=mat, alpha=False)img = Image.open(io.BytesIO(pix.tobytes()))images.append(img)if len(images) == 1:images[0].save(output_path)else:# 计算总高度和最大宽度total_height = sum(img.height for img in images)max_width = max(img.width for img in images)# 如果总高度超过限制,分割图像max_height = 65000  # PIL的最大支持高度if total_height > max_height:parts = []current_height = 0current_part = []for img in images:if current_height + img.height > max_height:parts.append(current_part)current_part = [img]current_height = img.heightelse:current_part.append(img)current_height += img.heightif current_part:parts.append(current_part)# 保存每个部分base_name, ext = os.path.splitext(output_path)for i, part in enumerate(parts):part_height = sum(img.height for img in part)combined_img = Image.new('RGB', (max_width, part_height), (255, 255, 255))y_offset = 0for img in part:combined_img.paste(img, (0, y_offset))y_offset += img.heightpart_output_path = f"{base_name}_part{i + 1}{ext}"combined_img.save(part_output_path)print(f"输出文件(部分 {i + 1})已保存到: {part_output_path}")else:# 如果总高度没有超过限制,按原方式处理combined_img = Image.new('RGB', (max_width, total_height), (255, 255, 255))y_offset = 0for img in images:combined_img.paste(img, (0, y_offset))y_offset += img.heightcombined_img.save(output_path)print(f"输出文件已保存到: {output_path}")elif output_format == 'pdf':new_doc = fitz.open()for page_num in pages_to_process:new_doc.insert_pdf(doc, from_page=page_num - 1, to_page=page_num - 1)new_doc.save(output_path)print(f"输出文件已保存到: {output_path}")else:raise ValueError(f"不支持的输出格式: {output_format}")doc.close()def merge_pdfs(input_pdfs, output_path):merged_doc = fitz.open()for pdf_path in input_pdfs:with fitz.open(pdf_path) as doc:merged_doc.insert_pdf(doc)merged_doc.save(output_path)print(f"合并的PDF文件已保存到: {output_path}")def extract_images_from_pdf(pdf_path, page_range_str, output_directory):doc = fitz.open(pdf_path)total_pages = len(doc)pages_to_process = parse_page_ranges(page_range_str, total_pages)if not os.path.exists(output_directory):os.makedirs(output_directory)for page_num in pages_to_process:page = doc[page_num - 1]image_list = page.get_images()for img_index, img in enumerate(image_list):xref = img[0]base_image = doc.extract_image(xref)image_bytes = base_image["image"]# 获取图片格式image_format = base_image["ext"]# 使用 PIL 打开图片image = Image.open(io.BytesIO(image_bytes))# 保存图片image_filename = f"page_{page_num}_image_{img_index + 1}.{image_format}"image_path = os.path.join(output_directory, image_filename)image.save(image_path)print(f"已保存图片: {image_path}")print(f"所有图片已提取到目录: {output_directory}")def encrypt_pdf(input_path, output_path, user_password, owner_password=None):doc = fitz.open(input_path)if owner_password is None:owner_password = user_passwordencryption_method = fitz.PDF_ENCRYPT_AES_256permissions = int(fitz.PDF_PERM_ACCESSIBILITY| fitz.PDF_PERM_PRINT| fitz.PDF_PERM_COPY| fitz.PDF_PERM_ANNOTATE)doc.save(output_path,encryption=encryption_method,user_pw=user_password,owner_pw=owner_password,permissions=permissions)print(f"已加密的PDF保存到: {output_path}")def decrypt_pdf(input_path, output_path, password):doc = fitz.open(input_path)if doc.is_encrypted:if doc.authenticate(password):doc.save(output_path)print(f"已解密的PDF保存到: {output_path}")else:raise ValueError("密码不正确")else:print("PDF文件未加密")doc.save(output_path)print(f"PDF文件已复制到: {output_path}")def main():parser = argparse.ArgumentParser(description="处理PDF文件:选择页面并输出为JPG、PNG或PDF,或合并多个PDF,或提取图片")subparsers = parser.add_subparsers(dest='command', help='可用的命令')# 处理单个PDF的命令process_parser = subparsers.add_parser('process', help='处理单个PDF文件')process_parser.add_argument("input_pdf", help="输入PDF文件的路径")process_parser.add_argument("page_range", help="要处理的页面范围,例如 '1,3-5,7-9'")process_parser.add_argument("output", help="输出文件的路径(支持.jpg, .jpeg, .png, .pdf)")process_parser.add_argument("-d", "--dpi", type=int, default=300, help="图像DPI (仅用于jpg和png输出,默认: 300)")process_parser.add_argument("-p", "--password", help="PDF密码(如果PDF加密)")process_parser.add_argument("-s", "--split-pages", action='store_true', help="按每页生成单独的JPG或PNG文件")# 合并PDF的命令merge_parser = subparsers.add_parser('merge', help='合并多个PDF文件')merge_parser.add_argument("input_pdfs", nargs='+', help="要合并的PDF文件路径列表")merge_parser.add_argument("output", help="输出的合并PDF文件路径")# 提取图片的命令extract_parser = subparsers.add_parser('extract', help='从PDF中提取图片')extract_parser.add_argument("input_pdf", help="输入PDF文件的路径")extract_parser.add_argument("page_range", help="要提取图片的页面范围,例如 '1,3-5,7-9'")extract_parser.add_argument("output_directory", help="保存提取图片的目录路径")extract_parser.add_argument("-p", "--password", help="PDF密码(如果PDF加密)")# 加密PDF的命令encrypt_parser = subparsers.add_parser('encrypt', help='加密PDF文件')encrypt_parser.add_argument("input_pdf", help="输入PDF文件的路径")encrypt_parser.add_argument("output_pdf", help="输出加密PDF文件的路径")encrypt_parser.add_argument("user_password", help="用户密码")encrypt_parser.add_argument("-o", "--owner_password", help="所有者密码(如果不提供,将与用户密码相同)")# 解密PDF的命令decrypt_parser = subparsers.add_parser('decrypt', help='解密PDF文件')decrypt_parser.add_argument("input_pdf", help="输入加密PDF文件的路径")decrypt_parser.add_argument("output_pdf", help="输出解密PDF文件的路径")decrypt_parser.add_argument("password", help="PDF密码")args = parser.parse_args()if args.command == 'process':try:decrypted_pdf_path = try_remove_pdf_password(args.input_pdf, args.password)process_pdf(decrypted_pdf_path, args.page_range, args.output, args.dpi, args.split_pages)if decrypted_pdf_path != args.input_pdf:os.remove(decrypted_pdf_path)except ValueError as e:if "PDF文件已加密,需要密码" in str(e):password = input("请输入PDF密码: ")try:decrypted_pdf_path = try_remove_pdf_password(args.input_pdf, password)process_pdf(decrypted_pdf_path, args.page_range, args.output, args.dpi, args.split_pages)except ValueError as e:print(f"处理过程中出错: {str(e)}")else:print(f"处理过程中出错: {str(e)}")except Exception as e:print(f"处理过程中出错: {str(e)}")elif args.command == 'merge':try:merge_pdfs(args.input_pdfs, args.output)except Exception as e:print(f"合并PDF过程中出错: {str(e)}")elif args.command == 'extract':try:decrypted_pdf_path = try_remove_pdf_password(args.input_pdf, args.password)extract_images_from_pdf(decrypted_pdf_path, args.page_range, args.output_directory)if decrypted_pdf_path != args.input_pdf:os.remove(decrypted_pdf_path)except ValueError as e:if "PDF文件已加密,需要密码" in str(e):password = input("请输入PDF密码: ")try:decrypted_pdf_path = try_remove_pdf_password(args.input_pdf, password)extract_images_from_pdf(decrypted_pdf_path, args.page_range, args.output_directory)except ValueError as e:print(f"处理过程中出错: {str(e)}")else:print(f"处理过程中出错: {str(e)}")except Exception as e:print(f"处理过程中出错: {str(e)}")elif args.command == 'encrypt':try:encrypt_pdf(args.input_pdf, args.output_pdf, args.user_password, args.owner_password)except Exception as e:print(f"加密PDF过程中出错: {str(e)}")elif args.command == 'decrypt':try:decrypt_pdf(args.input_pdf, args.output_pdf, args.password)except Exception as e:print(f"解密PDF过程中出错: {str(e)}")if __name__ == "__main__":main()

使用方法

1. 处理 PDF

python pdf_tool.py process[options]
  • 参数说明:

: 输入 PDF 文件的路径 

: 要处理的页面范围,例如 '1,3-5,7-9' 

: 输出文件的路径(支持 。jpg, .jpeg, .png, .pdf)  

  • 选项:

-d, --dpi: 设置图像 DPI(默认:300) 

-p, --password: PDF 密码(如果 PDF 加密) 

-s, --split-pages: 按每页生成单独的 JPG 或 PNG 文件 

  • 示例:
python pdf_tool.py process input.pdf 1,3-5 output.png -d 200 -s

 

2. 合并 PDF

python pdf_tool.py merge
  • 参数说明:

: 要合并的 PDF 文件路径列表 

: 输出的合并 PDF 文件路径 

  • 示例:
python pdf_tool.py merge file1.pdf file2.pdf file3.pdf merged.pdf

 

3. 提取图片

python pdf_tool.py extract[options]
  • 参数说明:

: 输入 PDF 文件的路径 

: 要提取图片的页面范围,例如 '1,3-5,7-9' 

: 保存提取图片的目录路径 

  • 选项:

-p, --password: PDF 密码(如果 PDF 加密) 

  • 示例:
python pdf_tool.py extract document.pdf 1-5 ./images -p mypassword

 

4. 加密 PDF

python pdf_tool.py encrypt[options]
  • 参数说明:

: 输入 PDF 文件的路径 

: 输出加密 PDF 文件的路径 

: 用户密码 

  • 选项:

-o, --owner_password: 所有者密码(如果不提供,将与用户密码相同) 

  • 示例:
python pdf_tool.py encrypt input.pdf encrypted.pdf userpass -o ownerpass

 

5. 解密 PDF

python pdf_tool.py decrypt
  • 参数说明:

: 输入加密 PDF 文件的路径 

: 输出解密 PDF 文件的路径 

: PDF 密码 

  • 示例:
python pdf_tool.py decrypt encrypted.pdf decrypted.pdf mypassword


相关阅读

基于 DeepSeek+AutoGen 的智能体协作系统

AI 时代,如何用 Python 脚本轻松搞定 PDF 需求?

DeepSeek V3 vs R1:到底哪个更适合你?全面对比来袭

深度揭秘:如何用一句话让 DeepSeek 优化你的代码

手把手教你用 DeepSeek 和 VSCode 开启 AI 辅助编程之旅

零基础小白的编程入门:用 AI 工具轻松加功能、改代码

http://www.dtcms.com/wzjs/18676.html

相关文章:

  • 深圳企业网站制作设计企业网站seo优化公司
  • 网站建设的评分细则百度推广怎么找客户
  • 网站首页图片做多大爱站网seo综合查询工具
  • 网站开发公司网站搜索引擎优化到底是优化什么
  • 销售做网站房地产市场现状分析
  • wordpress做网站优点搜索引擎营销案例分析题
  • 代购网站建设微信推广怎么弄
  • 微网站建设渠道win10优化大师
  • 优秀的vi设计手册南京seo顾问
  • 精选网站建设网店推广方案
  • 做网站什么软件品牌营销网站建设
  • 网站整合discuz论坛网络推广及销售
  • 公司网站建设策划书飞猪关键词排名优化
  • 国内做设计的网站有哪些潍坊网站建设优化
  • 广州环保网站建设常州网站建设制作
  • 淘客免费网站建设域名备案查询站长工具
  • 改wordpress的wp_admin深圳网站seo优化公司
  • 网站建设调研提纲站长工具seo综合查询怎么使用的
  • 官网型网站开发友情链接多久有效果
  • 做国外直播网站有哪些网站排名优化首页
  • 会展类网站模板引擎搜索下载
  • 进什么网站接模具做冯耀宗seo课程
  • 网站的组成部分怎么建立自己的网页
  • 云南网站建设哪个好靠谱的代写平台
  • 广西汽车网网站建设seo是什么意思?
  • 安徽网站搭建东莞市优速网络科技有限公司
  • 网站建设皖icp做个公司网站一般需要多少钱
  • 江苏 建设 招标有限公司网站广州市最新消息
  • 网络公司网站首页图片百度关键词排名怎么靠前
  • 楚雄网站制作色目人