通过调整尺寸压缩 PNG 图片并转换为 PDF
1. 环境准备
确保已经安装了 Python 和所需的库。如果尚未安装,可以使用以下命令:
bash
pip install Pillow reportlab
2. 代码实现
以下是完整的 Python 程序,用于通过缩小图片尺寸来压缩 PNG 图片并将其保存为 PDF 格式:
python
from PIL import Image
from reportlab.pdfgen import canvas
def compress_and_convert_to_pdf(input_png_path, output_pdf_path, scale=0.2):
# 打开 PNG 图片
img = Image.open(input_png_path)
# 如果图片是 RGBA 模式,转换为 RGB 模式
if img.mode == 'RGBA':
img = img.convert('RGB')
# 获取原始尺寸
original_width, original_height = img.size
# 计算压缩后的尺寸
new_width = int(original_width * scale)
new_height = int(original_height * scale)
# 调整尺寸
img = img.resize((new_width, new_height), Image.ANTIALIAS)
# 保存压缩后的图片为 JPEG 格式
compressed_img_path = 'compressed_image.jpg'
img.save(compressed_img_path, 'JPEG', quality=85)
# 使用 reportlab 创建 PDF
c = canvas.Canvas(output_pdf_path, pagesize=(new_width, new_height))
# 将图片绘制到 PDF 上
c.drawImage(compressed_img_path, 0, 0, width=new_width, height=new_height)
# 保存 PDF
c.save()
print(f'PDF saved at: {output_pdf_path}')
# 示例用法
input_png = "input_image.png" # 替换为 PNG 图片路径
output_pdf = "output_file.pdf" # 替换为希望输出的 PDF 文件名
compress_and_convert_to_pdf(input_png, output_pdf, scale=0.2)
3. 程序解释
- 导入库 :使用
PIL
库来处理图片,使用reportlab
来生成 PDF。 - 打开 PNG 图片 :使用
Image.open()
函数打开指定路径的 PNG 图片。 - 模式转换:如果图片为 RGBA 模式,则将其转换为 RGB 模式,以避免 JPEG 格式不支持透明度的问题。
- 计算新尺寸 :根据
scale
参数(默认为 0.2,即缩小至原始尺寸的 20%)计算新的宽度和高度。 - 调整图片尺寸 :使用
img.resize()
方法将图片缩小。 - 保存 JPEG 格式:将调整后的图片保存为 JPEG 格式。可以设置质量参数(范围为 1-100)。
- 创建 PDF 文件 :
- 使用
canvas.Canvas()
创建一个 PDF 对象,设置页面大小为图片的新尺寸。 - 使用
drawImage()
方法将压缩后的图片绘制到 PDF 页面上。
- 使用
- 保存 PDF 文件 :调用
c.save()
保存 PDF 文件。
4. 使用方法
- 将
input_png
设置为 PNG 图片的路径。 - 将
output_pdf
设置为希望输出的 PDF 文件名或路径。 - 运行程序后,将得到一个包含压缩 PNG 图片的 PDF 文件。
5. 注意事项
- 由于 JPEG 格式不支持透明度,如果 PNG 图片包含透明区域,这些区域在转换时将变为白色。
- 可以根据需要调整
scale
参数来获得不同的压缩效果。 - 确保使用的 PNG 图片路径正确,否则程序会报错。
通过这个教程,可以有效地通过调整尺寸来压缩 PNG 图片,并将其转换为 PDF 格式!
批量处理文件
创建CompressPng.py
程序,包含以下内容:
python
#!/usr/bin/env python
import re
import sys
from PIL import Image
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
def compress_and_convert_to_pdf_v2(input_png_path, output_pdf_path, scale=0.2):
# 打开PNG图片
img = Image.open(input_png_path)
# 如果图片是RGBA模式,转换为RGB模式
if img.mode == 'RGBA':
img = img.convert('RGB')
# 获取原始尺寸
original_width, original_height = img.size
# 计算压缩后的尺寸
new_width = int(original_width * scale)
new_height = int(original_height * scale)
# 调整尺寸
img = img.resize((new_width, new_height), Image.ANTIALIAS)
# 保存压缩后的图片为JPEG格式(这里可以跳过保存中间文件的步骤)
compressed_img_path = 'compressed_image.jpg'
img.save(compressed_img_path, 'JPEG', quality=85)
# 使用 reportlab 将压缩后的图片转换为PDF
c = canvas.Canvas(output_pdf_path, pagesize=(new_width, new_height))
# 将图片绘制到PDF上
c.drawImage(compressed_img_path, 0, 0, width=new_width, height=new_height)
# 保存PDF
c.save()
print(f'PDF saved at: {output_pdf_path}')
def compress_and_convert_to_pdf(input_png_path, output_pdf_path, quality=85):
# 打开PNG图片
img = Image.open(input_png_path)
# 如果图片是RGBA模式,转换为RGB模式
if img.mode == 'RGBA':
img = img.convert('RGB')
# 压缩图片并保存为JPEG格式
compressed_img_path = 'compressed_image.jpg'
img.save(compressed_img_path, 'JPEG', quality=quality)
# 使用reportlab将压缩后的图片转换为PDF
img_width, img_height = img.size
c = canvas.Canvas(output_pdf_path, pagesize=(img_width, img_height))
# 将图片绘制到PDF上
c.drawImage(compressed_img_path, 0, 0, width=img_width, height=img_height)
# 保存PDF
c.save()
print(f'PDF saved at: {output_pdf_path}')
def get_filename(arg):
'''
get the input file name
'''
file_list = []
for iarg in arg:
if iarg.split('.')[-1] == "png":
file_list.append(iarg)
if len(file_list) >= 1:
return file_list
else:
print("\n")
print("-"*10)
print("\n")
print("Please Check whether the input file is png picture\n")
print("-"*10)
#Usage()
print("\n")
if __name__ == '__main__':
arg = sys.argv
file_list = get_filename(arg)
for filename in file_list:
# 示例用法
input_png = filename
output_pdf = filename.split('.')[0]+".pdf"
compress_and_convert_to_pdf_v2(input_png, output_pdf, scale=0.6)
使用方法
可在程序后接入多个png
文件路径,或者接*.png
以实现批量处理:
shell
python CompressPng.py 001.png 002.png
python CompressPng.py *.png
如果想要更改缩放比例,需要在程序中更改 scale
的值。