Python脚本实现批量修改图片DPI
做学术论文、投期刊的朋友应该都懂,图片DPI这玩意儿平时不起眼,投稿的时候真能急死人。大部分期刊都要求300dpi以上,有的甚至要600dpi。但平时ArcGIS出图、截图啥的,默认都是72或者96dpi,每次投稿前都得一张张改,烦得要死。
之前用PS批量处理也麻烦,还容易卡。索性自己写了个Python脚本,把整个文件夹的图片全丢进去,一键搞定。亲测好用,分享给大家。
先说下DPI这事儿
很多人搞不清,其实改DPI不改变图片本身的像素,就是改个"打印清晰度标识"。简单说:
- 72/96dpi:屏幕看看还行,打印就糊
- 300dpi:普通印刷够用
- 600dpi:学术论文、学位论文基本都要这个标准
所以改DPI不是把小图放大,只是告诉打印机"这图按高清来印"。
脚本怎么写的
直接上代码,我把注释都写清楚了,小白也能用。
核心部分其实就几行
最关键的就是Pillow这个库的save方法,给它传dpi参数就行:
from PIL import Image
# 打开图片
with Image.open("你的图片.jpg") as img:
# 保存的时候设置DPI
img.save("输出.jpg", dpi=(600, 600), quality=95)
就这么简单。JPG的话加个quality=95,画质损失很小。PNG是无损的,直接设dpi就行。
完整的批量处理版本
我加了遍历文件夹、格式过滤、异常处理这些,直接用就行:
from PIL import Image
import os
# ========== 这里改路径就行 ==========
INPUT_FOLDER = r".\input" # 把要处理的图放这个文件夹
OUTPUT_FOLDER = r".\output" # 处理完自动存在这里
TARGET_DPI = (600, 600) # 论文就用600,不用改
# ==================================
# 自动创建输出文件夹
os.makedirs(OUTPUT_FOLDER, exist_ok=True)
count_ok = 0
count_skip = 0
print("开始处理...\n")
for filename in os.listdir(INPUT_FOLDER):
filepath = os.path.join(INPUT_FOLDER, filename)
# 跳过文件夹
if not os.path.isfile(filepath):
continue
# 只处理图片
ext = os.path.splitext(filename)[1].lower()
if ext not in ('.png', '.jpg', '.jpeg'):
count_skip += 1
print(f"跳过: {filename}")
continue
try:
with Image.open(filepath) as img:
params = {'dpi': TARGET_DPI}
# JPG额外加画质参数
if ext in ('.jpg', '.jpeg'):
params['quality'] = 95
params['subsampling'] = 0
# 保存
img.save(os.path.join(OUTPUT_FOLDER, filename), **params)
count_ok += 1
print(f"完成: {filename}")
except Exception as e:
count_skip += 1
print(f"失败: {filename} | {str(e)}")
# 最后统计
print("\n" + "-"*40)
print(f"处理完了!成功: {count_ok} 张,跳过: {count_skip} 个")
print(f"文件存在这里: {os.path.abspath(OUTPUT_FOLDER)}")
print("-"*40)
怎么用
先装依赖:
pip install Pillow
脚本旁边新建个叫input的文件夹,把所有要改的图都扔进去
运行脚本,完事去output文件夹拿就行
验证的话,Windows右键图片→属性→详细信息里就能看到DPI变了
踩过的坑
JPG要设quality=95:默认的保存质量太低,图会糊。设95几乎看不出区别,文件也不会太大
大小写问题:有的图片是.JPG大写,判断后缀的时候记得转小写
图片被占用:如果图片在PS或者其他软件里开着,会保存失败,关了就行
TIFF格式:如果要处理tif,在格式判断里加上就行
亲测处理几百张图也就几秒钟,比PS动作快多了。做GIS、遥感的同学,出的那些专题图、示意图,用这个批量处理完直接就能插论文里。
知识扩展
Python 脚本实现批量修改图片 DPI
修改图片的 DPI(每英寸点数)通常有两种需求:
- 仅修改元数据(不改变像素尺寸):常用于满足打印或出版要求,图像像素不变,但物理尺寸(英寸)会变化。
- 公式:
物理尺寸(英寸) = 像素尺寸 / DPI - 按目标 DPI 重采样图像:改变像素数量,从而改变文件大小和清晰度。
以下脚本基于 Pillow 库,支持两种模式,并可以递归批量处理文件夹中的所有图片。
1. 安装依赖
pip install Pillow
2. 批量修改 DPI 元数据(不改变像素)
import os
from PIL import Image
def batch_set_dpi_metadata(input_dir, output_dir, target_dpi=300, extensions=('.jpg', '.jpeg', '.png', '.tiff', '.bmp')):
"""
批量修改图片的 DPI 元数据,不改变像素尺寸。
:param input_dir: 输入文件夹路径
:param output_dir: 输出文件夹路径(如果与输入相同,会覆盖原文件)
:param target_dpi: 目标 DPI (整数,如 300)
:param extensions: 处理的文件扩展名元组
"""
os.makedirs(output_dir, exist_ok=True)
for filename in os.listdir(input_dir):
if not filename.lower().endswith(extensions):
continue
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
with Image.open(input_path) as img:
# 注意:PNG 格式不支持保存 DPI 信息,建议转换为 JPEG 或 TIFF
# 如果输出格式为 PNG,Pillow 可能忽略 info['dpi'] 设置
if img.format == 'PNG' and output_path.lower().endswith('.png'):
print(f"警告:PNG 格式不支持 DPI 元数据,将转换为 JPEG 保存: {filename}")
output_path = os.path.splitext(output_path)[0] + '.jpg'
img = img.convert('RGB') # PNG 可能有透明通道,需转为 RGB
# 修改 DPI 元数据
img.info['dpi'] = (target_dpi, target_dpi)
# 保存时保留 dpi 信息(JPEG/TIFF 等格式支持)
img.save(output_path, dpi=(target_dpi, target_dpi))
print(f"已处理: {filename} -> {target_dpi} DPI (元数据)")
# 示例:将 input_images 文件夹中所有图片的 DPI 元数据改为 300,输出到 output_dpi 文件夹
batch_set_dpi_metadata('./input_images', './output_dpi', target_dpi=300)3. 按目标 DPI 重采样图像(改变像素尺寸)
如果你想保持物理尺寸不变(比如希望打印出来仍是 10x10 厘米),则需要根据目标 DPI 重新计算像素尺寸并缩放图像。
import os
from PIL import Image
def batch_resize_by_dpi(input_dir, output_dir, target_dpi=300, extensions=('.jpg', '.jpeg', '.png', '.tiff')):
"""
根据目标 DPI 重采样图像,使打印物理尺寸保持不变。
例如:原图 300x300 像素,100 DPI -> 物理尺寸 3x3 英寸。
改为 300 DPI 后,像素变为 900x900,物理尺寸仍为 3x3 英寸。
:param input_dir: 输入文件夹
:param output_dir: 输出文件夹
:param target_dpi: 目标 DPI
"""
os.makedirs(output_dir, exist_ok=True)
for filename in os.listdir(input_dir):
if not filename.lower().endswith(extensions):
continue
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
with Image.open(input_path) as img:
# 获取原始 DPI(如果无则默认 72)
src_dpi = img.info.get('dpi', (72, 72))[0]
if src_dpi == target_dpi:
print(f"跳过 {filename},已经是 {target_dpi} DPI")
# 但仍复制文件到输出目录(可选)
img.save(output_path)
continue
# 计算缩放比例
ratio = target_dpi / src_dpi
new_width = int(img.width * ratio)
new_height = int(img.height * ratio)
# 重采样(使用高质量滤波器)
resized_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
# 保存并设置新 DPI 元数据
resized_img.save(output_path, dpi=(target_dpi, target_dpi))
print(f"已处理: {filename} | 原DPI:{src_dpi} -> 新DPI:{target_dpi} | 尺寸:{img.width}x{img.height} -> {new_width}x{new_height}")
# 示例:将所有图片重采样为 300 DPI,保持物理尺寸不变
batch_resize_by_dpi('./input_images', './output_dpi_resampled', target_dpi=300)4. 仅修改 JPEG 的 EXIF 中的 DPI(更底层)
某些专业应用要求精确写入 EXIF 的 XResolution/YResolution 标签,使用 piexif 库可以更可靠地修改 JPEG 的 DPI 元数据。
pip install piexif
import os
import piexif
from PIL import Image
def batch_set_dpi_exif(input_dir, output_dir, target_dpi=300):
os.makedirs(output_dir, exist_ok=True)
for filename in os.listdir(input_dir):
if not filename.lower().endswith(('.jpg', '.jpeg')):
continue
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
img = Image.open(input_path)
try:
exif_dict = piexif.load(img.info.get('exif', b''))
except:
exif_dict = {"0th": {}, "Exif": {}, "GPS": {}, "1st": {}}
# 设置 XResolution 和 YResolution (单位: 像素/英寸)
exif_dict['0th'][piexif.ImageIFD.XResolution] = (target_dpi, 1)
exif_dict['0th'][piexif.ImageIFD.YResolution] = (target_dpi, 1)
exif_dict['0th'][piexif.ImageIFD.ResolutionUnit] = 2 # 2 表示英寸
exif_bytes = piexif.dump(exif_dict)
img.save(output_path, exif=exif_bytes)
print(f"已更新 EXIF DPI: {filename} -> {target_dpi}")
batch_set_dpi_exif('./input_images', './output_exif', target_dpi=300)到此这篇关于Python脚本实现批量修改图片DPI的文章就介绍到这了,更多相关Python修改图片DPI内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!


最新评论