鱼C论坛

 找回密码
 立即注册
查看: 651|回复: 9

[已解决]PDF转换问题?合成后尺寸变了

[复制链接]
发表于 2024-6-11 14:48:34 | 显示全部楼层 |阅读模式
15鱼币
本帖最后由 任申猴 于 2024-6-11 14:51 编辑

源文件:竖向的在浏览器打开100%状态看着是正常的;
1.png

由于需要把它转为图片在转成PDF(避免抠图)
  1. import os
  2. import fitz
  3. from PIL import Image
  4. import shutil
  5. import re
  6. import win32com.client as win32

  7. def excel_to_pdf():
  8.     """当前黑白版转PDF"""
  9.     current_directory = os.getcwd()
  10.     xls_files = [f for f in os.listdir(current_directory) if f.endswith('.xls')]
  11.     if not xls_files:
  12.         print('当前目录下没有 .xls 文件')
  13.         return

  14.     xls_file_names = [os.path.splitext(f)[0] for f in xls_files]
  15.     xls_path = os.path.join(current_directory, xls_files[0])
  16.     pdf_out_path = current_directory

  17.     if not os.path.exists(pdf_out_path):
  18.         os.makedirs(pdf_out_path)

  19.     excel = win32.gencache.EnsureDispatch('Excel.Application')
  20.     excel.Visible = False
  21.     workbook = excel.Workbooks.Open(xls_path)
  22.     pdf_path = os.path.join(pdf_out_path, f"{xls_file_names[0]}_报告.pdf")
  23.     workbook.ExportAsFixedFormat(0, pdf_path)
  24.     workbook.Close(False)
  25.     excel.Application.Quit()

  26.     result = re.search(r'\d+', pdf_path)
  27.     if result:
  28.         number_only = result.group()
  29.     pdf_name = f'LTJC{number_only}_报告.pdf'
  30.     rightmost_index = len(pdf_name) - 4
  31.     folder_name = pdf_name[:rightmost_index]

  32.     if not os.path.exists(folder_name):
  33.         os.makedirs(folder_name)
  34.         print(f"文件夹 '{folder_name}' 已成功创建。")
  35.     else:
  36.         print(f"文件夹 '{folder_name}' 已经存在。")

  37.     doc = fitz.open(pdf_name)

  38.    
  39.     dpi = 300  
  40.     zoom = dpi / 72  # PDF 默认是 72 DPI
  41.     mat = fitz.Matrix(zoom, zoom)

  42.     for page_num in range(len(doc)):
  43.         page = doc[page_num]
  44.         pix = page.get_pixmap(matrix=mat)
  45.         output = os.path.join(folder_name, f"page_{page_num}.png")
  46.         pix.save(output)

  47.     doc.close()

  48.     if os.path.exists(pdf_name):
  49.         os.remove(pdf_name)
  50.         print(f'文件 {pdf_name} 已成功删除')
  51.     else:
  52.         print(f'文件 {pdf_name} 不存在')

  53.     image_folder = folder_name
  54.     image_files = [f for f in os.listdir(image_folder) if f.endswith('.png')]
  55.     image_files.sort(key=lambda x: int(x.split('_')[1].split('.')[0]))

  56.     images = []
  57.     for image_file in image_files:
  58.         img_path = os.path.join(image_folder, image_file)
  59.         img = Image.open(img_path)
  60.         if img.mode == 'RGBA':
  61.             img = img.convert('RGB')
  62.         print(dpi)
  63.         a4_width, a4_height = (2480, 3508)
  64.         # if dpi == 600:
  65.         #     a4_width, a4_height = (4960, 7016)
  66.         # elif dpi == 1200:
  67.         #     a4_width, a4_height = (9920, 14032)

  68.         img = img.resize((a4_width, a4_height), Image.Resampling.LANCZOS)
  69.         jpg_path = os.path.join(image_folder, f"page_{image_file.split('_')[1].split('.')[0]}.png")
  70.         img.save(jpg_path, format='JPEG', quality=85)

  71.         images.append(Image.open(jpg_path))

  72.     pdf_path = pdf_name[:15] + '_报告.pdf'
  73.     images[0].save(pdf_path, save_all=True, append_images=images[1:])

  74.     folder_path = folder_name
  75.     if os.path.exists(folder_path):
  76.         shutil.rmtree(folder_path)
  77.         print(f'文件夹 {folder_path} 已成功删除')
  78.     else:
  79.         print(f'文件夹 {folder_path} 不存在')

  80.     print(number_only)

  81.     return pdf_path, xls_file_names
  82. excel_to_pdf()
复制代码



转换出来了 ,图片变大了 ,在浏览器打开100%状态下,大了几倍,但我设置的是300dpi  ,请问大佬这是为什么?

2.png


最佳答案
2024-6-11 14:48:35
  1. images[0].save(output_pdf_path, save_all=True, append_images=images[1:],resolution=300,quality=100,optims=True)
复制代码

解决了,需要把这几个参数指定了

最佳答案

查看完整内容

解决了,需要把这几个参数指定了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-6-11 14:48:35 | 显示全部楼层    本楼为最佳答案   
  1. images[0].save(output_pdf_path, save_all=True, append_images=images[1:],resolution=300,quality=100,optims=True)
复制代码

解决了,需要把这几个参数指定了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-6-11 14:49:06 | 显示全部楼层
在进行PDF转换时,会涉及到一些尺寸的调整问题。有时候,转换后的PDF文件的尺寸可能与源文件不一致。这可能是由于转换工具在处理过程中对尺寸进行了调整。

为了解决这个问题,你可以尝试使用Python中的一个PDF处理库PyPDF2来进行转换,并在转换过程中指定输出的尺寸。下面是一个示例代码:

  1. import PyPDF2

  2. def convert_pdf(source_path, output_path, width=None, height=None):
  3.     # 打开源文件
  4.     with open(source_path, 'rb') as source_file:
  5.         # 创建一个PDF读取器对象
  6.         reader = PyPDF2.PdfReader(source_file)
  7.         
  8.         # 创建一个PDF写入器对象
  9.         writer = PyPDF2.PdfWriter()
  10.         
  11.         # 遍历每一页
  12.         for page in reader.pages:
  13.             # 获取源页面的尺寸
  14.             page_width = page.mediaBox[2]
  15.             page_height = page.mediaBox[3]
  16.             
  17.             # 如果指定了输出尺寸,则调整页面尺寸
  18.             if width and height:
  19.                 page.scaleTo(width, height)
  20.             
  21.             # 将调整后的页面添加到写入器对象中
  22.             writer.add_page(page)
  23.         
  24.         # 将写入器对象保存到输出文件中
  25.         with open(output_path, 'wb') as output_file:
  26.             writer.write(output_file)

  27. # 调用函数进行PDF转换
  28. convert_pdf('source.pdf', 'output.pdf', width=500, height=700)
复制代码


在上面的代码中,`convert_pdf`函数接受源文件路径、输出文件路径以及可选的输出尺寸作为参数。如果没有指定输出尺寸,将保持源文件的尺寸。可以根据自己的需求进行调整。

希望这个示例能够帮助到你解决问题!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-6-11 15:46:14 | 显示全部楼层
貌似,dpi没有生效,稍等我来测试下代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-6-11 15:51:58 | 显示全部楼层
鱼油代码中涉及将 Excel 文件转换为 PDF,再将 PDF 页面转换为图片,并最终调整图片大小以适应 A4 页面,保存为 JPEG 格式。

转换过程中出现的图像放大问题可能源于几个关键环节:

  • PDF 分辨率与显示分辨率的关系:您的代码中将 PDF 页面的分辨率设置为 300 DPI(点每英寸),然后将此图像缩放到 A4 纸的分辨率(2480x3508 像素)。这种缩放假设了 DPI 与尺寸的直接关系,即图片的物理尺寸会随着 DPI 的改变而线性缩放。
  • 图像缩放逻辑:代码中使用 Image.Resampling.LANCZOS 方法进行图像缩放,这是一种高质量的重采样算法,适合保持图像质量。然而,如果原始图像的尺寸(以像素计)与目标尺寸相差很大,该算法可能导致视觉上的放大或缩小。
  • DPI 与图像显示大小的误解:DPI 主要是一个打印设置,表示每英寸应该有多少个点,而在电脑屏幕上查看图像时,实际显示大小还取决于屏幕分辨率和图像的像素尺寸。尽管设置了 300 DPI,但图像的像素尺寸(宽度和高度)是决定其在屏幕上显示大小的关键因素。
  • 具体实现中的问题:代码将 PDF 页面转换为图像后,直接调整为 A4 的像素尺寸。如果原始 PDF 页面的实际像素尺寸小于或等于 A4 尺寸,这种调整可能无问题。但如果原始 PDF 页面的像素尺寸已经非常大(可能由于 PDF 的内部设置或内容本身的分辨率很高),则此调整可能导致图像在屏幕上显示得比预期更大。



解决方案:

  • 检查 PDF 的原始尺寸:在进行图像缩放之前,首先检查 PDF 页面的原始像素尺寸。可以使用工具或库来读取这些信息。
  • 适当调整图像尺寸:根据屏幕显示需要和打印需求调整图像的目标尺寸。如果原始图像尺寸远大于 A4 尺寸,应该相应减小缩放比例。
  • 调整 DPI 设置:如果主要关注屏幕显示效果而非打印,可以适当降低 DPI 设置,使其更适合屏幕显示的分辨率。

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-6-11 18:32:50 | 显示全部楼层
不二如是 发表于 2024-6-11 15:46
貌似,dpi没有生效,稍等我来测试下代码

咋看不了回复??
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-6-11 20:11:07 | 显示全部楼层
任申猴 发表于 2024-6-11 18:32
咋看不了回复??

现在呢?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-6-12 09:08:04 | 显示全部楼层

还是白版,AI生成的那个能看见,啥情况
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-6-12 09:33:43 | 显示全部楼层
任申猴 发表于 2024-6-12 09:08
还是白版,AI生成的那个能看见,啥情况


是不是因为你 resize 重新设置了尺寸了?

  1. import os
  2. import fitz
  3. from PIL import Image
  4. import shutil
  5. import re
  6. import win32com.client as win32

  7. def excel_to_pdf():
  8.     """当前黑白版转PDF"""
  9.     current_directory = os.getcwd()
  10.     xls_files = [f for f in os.listdir(current_directory) if f.endswith('.xls')]
  11.     if not xls_files:
  12.         print('当前目录下没有 .xls 文件')
  13.         return

  14.     xls_file_names = [os.path.splitext(f)[0] for f in xls_files]
  15.     xls_path = os.path.join(current_directory, xls_files[0])
  16.     pdf_out_path = current_directory

  17.     if not os.path.exists(pdf_out_path):
  18.         os.makedirs(pdf_out_path)

  19.     excel = win32.gencache.EnsureDispatch('Excel.Application')
  20.     excel.Visible = False
  21.     workbook = excel.Workbooks.Open(xls_path)
  22.     pdf_path = os.path.join(pdf_out_path, f"{xls_file_names[0]}_报告.pdf")
  23.     workbook.ExportAsFixedFormat(0, pdf_path)
  24.     workbook.Close(False)
  25.     excel.Application.Quit()

  26.     result = re.search(r'\d+', pdf_path)
  27.     if result:
  28.         number_only = result.group()
  29.     pdf_name = f'LTJC{number_only}_报告.pdf'
  30.     rightmost_index = len(pdf_name) - 4
  31.     folder_name = pdf_name[:rightmost_index]

  32.     if not os.path.exists(folder_name):
  33.         os.makedirs(folder_name)
  34.         print(f"文件夹 '{folder_name}' 已成功创建。")
  35.     else:
  36.         print(f"文件夹 '{folder_name}' 已经存在。")

  37.     doc = fitz.open(pdf_name)

  38.     dpi = 300  
  39.     zoom = dpi / 72  # PDF 默认是 72 DPI
  40.     mat = fitz.Matrix(zoom, zoom)

  41.     for page_num in range(len(doc)):
  42.         page = doc[page_num]
  43.         pix = page.get_pixmap(matrix=mat)
  44.         output = os.path.join(folder_name, f"page_{page_num}.png")
  45.         pix.save(output)

  46.     doc.close()

  47.     if os.path.exists(pdf_name):
  48.         os.remove(pdf_name)
  49.         print(f'文件 {pdf_name} 已成功删除')
  50.     else:
  51.         print(f'文件 {pdf_name} 不存在')

  52.     image_folder = folder_name
  53.     image_files = [f for f in os.listdir(image_folder) if f.endswith('.png')]
  54.     image_files.sort(key=lambda x: int(x.split('_')[1].split('.')[0]))

  55.     images = []
  56.     for image_file in image_files:
  57.         img_path = os.path.join(image_folder, image_file)
  58.         img = Image.open(img_path)
  59.         if img.mode == 'RGBA':
  60.             img = img.convert('RGB')
  61.         
  62.         # img = img.resize((a4_width, a4_height), Image.Resampling.LANCZOS)
  63.         
  64.         jpg_path = os.path.join(image_folder, f"page_{image_file.split('_')[1].split('.')[0]}.jpg")
  65.         img.save(jpg_path, format='JPEG', quality=85)
  66.         images.append(Image.open(jpg_path))

  67.     pdf_path = pdf_name[:15] + '_报告.pdf'
  68.     images[0].save(pdf_path, save_all=True, append_images=images[1:])

  69.     folder_path = folder_name
  70.     if os.path.exists(folder_path):
  71.         shutil.rmtree(folder_path)
  72.         print(f'文件夹 {folder_path} 已成功删除')
  73.     else:
  74.         print(f'文件夹 {folder_path} 不存在')
  75.     print(number_only)
  76.     return pdf_path, xls_file_names

  77. excel_to_pdf()
复制代码


试试 把 resize 注释了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-6-12 09:52:26 | 显示全部楼层
Twilight6 发表于 2024-6-12 09:33
是不是因为你 resize 重新设置了尺寸了?

不是,注释了还是,变大了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-21 14:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表