python cv2中如何让切片图片的DPI与原图保持一致?

How to keep DPI of sliced image the same as the original image in python cv2?

import cv2
img = 'image.jpg' # 300dpi
img = cv2.imread(img)
sliced_img = img(0:200,0:100)
cv2.imwrite('sliced.jpg',sliced_img) # 96dpi

有没有指定切片图像dpi的参数? 我想保留原来的 dpi 而不是更改 dpi...

这里是关于如何将输入图像中的 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")