这里有一个快速拼凑的想法,说明如何将APP0 段(包含 dpi)从输入图像复制到输出图像。 JPEG here 的解剖结构有一些相当合理的描述。
import cv2
import numpy as np
# Read input image with 300 dpi
im = cv2.imread('image.jpg')
# Grab its APP0 segment (with dpi) in first 18 bytes
with open('image.jpg', 'rb') as jpeg:
APP0 = jpeg.read(18)
# Process image ...
# Write result as JPEG to in-memory buffer
_, buffer = cv2.imencode(".jpg", im)
# Copy forward APP0 from original image
buffer[:18] = np.frombuffer(APP0, np.uint8)
# Write JPEG to disk with copied forward APP0
with open('result.jpg', 'wb') as out:
out.write(buffer)
用exiftool检查文件:
exiftool result.jpg
ExifTool Version Number : 12.30
File Name : result.jpg
Directory : .
File Size : 18 KiB
File Modification Date/Time : 2021:12:21 15:51:14+00:00
File Access Date/Time : 2021:12:21 15:51:23+00:00
File Inode Change Date/Time : 2021:12:21 15:51:22+00:00
File Permissions : -rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
JFIF Version : 1.01
Resolution Unit : inches
X Resolution : 300 <--- DPI HERE
Y Resolution : 300 <--- DPI HERE
Image Width : 640
Image Height : 480
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
Image Size : 640x480
Megapixels : 0.307
如果您不介意在项目中添加另一个依赖项,使用PyExifTool 可能更专业。
import exiftool
# Get dpi from input image
with exiftool.ExifTool() as et:
res = et.get_tags(['JFIF:XResolution','JFIF:YResolution'], 'image.jpg')
这就是res 的值:
{'SourceFile': 'image.jpg', 'JFIF:XResolution': 300, 'JFIF:YResolution': 300}
您可以将输出文件上的 dpi 设置为 10 或任何您想要的值,如下所示:
# You can probably omit the full path to exiftool if it is on your PATH
with exiftool.ExifTool("/opt/homebrew/bin/exiftool") as et:
et.execute(b"-JFIF:XResolution=10", b"result.jpg")
et.execute(b"-JFIF:YResolution=10", b"result.jpg")