1

I've already asked this question I didnot get satisfactory answers, So I did more research and I'm putting this question forward in a better way. I read an image through OpenCV imread method. And I saved it using imwrite method. It increases the output file size by more than double.

Below are the details of the images which I obtained from imagemagick ( I didnot write all the details down, I'm attaching the images for all the details are needed):

Input Image:

  • Format: JPEG (Joint Photographic Experts Group JFIF format)
    • Mime type: image/jpeg
    • Class: DirectClass
    • Geometry: 1836x3264+0+0
    • Resolution: 72x72
    • Print size: 25.5x45.3333
    • Units: PixelsPerInch
    • Type: TrueColor
    • Endianess: Undefined
    • Colorspace: sRGB
    • Depth: 8-bit
    • Channel depth: red: 8-bit green: 8-bit blue: 8-bit
    • Channel statistics: Pixels: 5992704
    • Compression: JPEG
    • Quality: 75
    • Filesize: 267KB
    • Number pixels: 5.993M

Output Image:

  • Format: JPEG (Joint Photographic Experts Group JFIF format)
    • Mime type: image/jpeg
    • Class: DirectClass
    • Geometry: 1836x3264+0+0
    • Units: Undefined
    • Type: TrueColor
    • Endianess: Undefined
    • Colorspace: sRGB
    • Depth: 8-bit
    • Channel depth: red: 8-bit green: 8-bit blue: 8-bit
    • Channel statistics: Pixels: 5992704
    • Compression: JPEG
    • Quality: 95
    • Filesize: 611KB
    • Number pixels: 5.993M

As you can see, the input image size is 267KB but the output image size turned out to be 611KB. Now I know that it size depends on the encoder, Compression value, bit-rate etc. I want to know is there anyway I can save the image in the exact same size of the input image.

I also tried using the compression in openCV like this cv2.imwrite('result.jpg', image, [int(cv2.IMWRITE_JPEG_QUALITY), 45]) Here the image quality would be 45, but the image size would still be greater than the input image ( around 300KB). I don't want to go less than 45 because it would affect the image details and loss of data.

I tried using external libraries like scipy, matplotlib. But they all bump the image size regardless.

Any clue on why the output image increase and how we can fix it is very much appreciated. Thanks.

Here is some code for reference

import cv2 #opencv library for image processing implementations 

def main():   
    im = cv2.imread('sample.jpg')
    cv2.imwrite('result.jpg', im)
    if(__name__=='__main__'):
      main()

And here is the image for reference. Sample Image

Beeti Sushruth
  • 311
  • 2
  • 11
  • You will get the same image, thus the same image size, if you save the image the way the original image was saved or generated in first place... Where does your original image come from, some cell phone? Do you have any information on how exactly the image is stored, which (JPEG) compression exactly is used? You can't expect any other software to have the exact same (JPEG) image saving than for example a (potential) highly adapted image saving software from some device, we don't know you used to take the original image in first place. You compare apples and oranges here, I'm afraid. – HansHirse Oct 14 '19 at 11:29
  • Hem, a copy will generate an image of exactly the same size. There is no point decompressing and recompressing. – Yves Daoust Oct 14 '19 at 11:55
  • @HansHirse My original image comes from cell phone. I don't have any idea on the JPEG compression it uses, I'm afraid. So you say, there is no way possible to save the image in it's original size from OpenCV. – Beeti Sushruth Oct 14 '19 at 12:17
  • @YvesDaoust I don't just want to copy it. Ofcourse there is some processing I want to do on the image before saving it. – Beeti Sushruth Oct 14 '19 at 12:17
  • @BeetiSushruth: if you modify the image, there is no reason it keeps the same size, even approximately. – Yves Daoust Oct 14 '19 at 12:24
  • By default the compression/quality factor being used by cv2 is higher and that's why you see the increased image size. You can mitigate this by passing the quality/compression threshold in the `cv2.write` function ex: `cv2.imwrite(path, image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])` here the jpg_quality value can be anything between 0-100. source: https://www.life2coding.com/save-opencv-images-jpeg-quality-png-compression/ – Neeraj Komuravalli May 27 '20 at 11:02

1 Answers1

1

Your original image has quality 75. If you don't define the quality of saving with OpenCV it defaults to 95, so you should expect the file to be larger.

If you want to set it to some maximum size, you can use ImageMagick like this to set it to, say 300kB:

convert sample.jpg -define jpeg:extent=300k a.jpg

And that gets you a 299,810 byte file with quality 83.

If you are prepared to permit 400kB, you can use:

convert sample.jpg -define jpeg:extent=400k a.jpg

and that gets you a 358,000 byte file with quality 93.


I wrote something similar in Python that lets you save at a specified size using a binary search here.

Mark Setchell
  • 169,892
  • 24
  • 238
  • 370