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

Is there any parameter to specify the dpi of sliced image? I want to keep the original dpi instead of changing the dpi...

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
  • 1
    Does this answer your question? [how to increase dpi with opencv?](https://stackoverflow.com/questions/50503960/how-to-increase-dpi-with-opencv) – SiHa Dec 21 '21 at 10:18
  • Actually, my other answer here is more helpful in changing the dpi... https://stackoverflow.com/a/57555123/2836621 – Mark Setchell Dec 21 '21 at 10:32
  • I have seen your answer , but I want to keep the original dpi instead of changing the dpi ... – Robert Chan Dec 21 '21 at 14:24
  • Ok, so read the dpi of the original image and set it in the output image. You can copy forward the whole APP0 segment if JPEG, see https://www.ccoderun.ca/programming/2017-01-31_jpeg/ I mean copy the first 18 bytes of your input file and replace the first 18 bytes of your output file with them. – Mark Setchell Dec 21 '21 at 15:06

1 Answers1

0

Here's a quickly hacked together idea of how you could copy forward the APP0 segment (which contains the dpi) from your input image to your output image. There is some pretty reasonable description of the anatomy of a 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)

Check file with 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

It is probably more professional to use PyExifTool, if you don't mind adding another dependency to your project.

import exiftool

# Get dpi from input image
with exiftool.ExifTool() as et:
    res = et.get_tags(['JFIF:XResolution','JFIF:YResolution'], 'image.jpg')

That gives this as the value for res:

 {'SourceFile': 'image.jpg', 'JFIF:XResolution': 300, 'JFIF:YResolution': 300}

And you can set the dpi on the output file to 10 or whatever you want like this:

# 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")
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432