By moomoochen


2018-09-10 13:59:06 8 Comments

In Python 3.x, I am using PIL to resize images, I know that we can reduce the height or width by subtraction or division by pixels. But, is it possible to resize an image to a desired size, say 200kb and remain its proportions? Assuming the image(s) is larger but the size is unknown.

1 comments

@Mark Setchell 2018-09-11 17:28:30

I am still learning Python, so there may be better ways, but here is a function that saves a PIL/Pillow image as a JPEG and allows you to specify a maximum size.

It uses a binary search to minimise the amount of work needed and it encodes into BytesIO memory buffer to save writing images to disk. If anyone has any suggestions for improvements, please let me know!

#!/usr/local/bin/python3

import io
import math
import sys
import numpy as np
from PIL import Image

def JPEGSaveWithTargetSize(im, filename, target):
   """Save the image as JPEG with the given name at best quality that makes less than "target" bytes"""
   # Min and Max quality
   Qmin, Qmax = 25, 96
   # Highest acceptable quality found
   Qacc = -1
   while Qmin <= Qmax:
      m = math.floor((Qmin + Qmax) / 2)

      # Encode into memory and get size
      buffer = io.BytesIO()
      im.save(buffer, format="JPEG", quality=m)
      s = buffer.getbuffer().nbytes

      if s <= target:
         Qacc = m
         Qmin = m + 1
      elif s > target:
         Qmax = m - 1

   # Write to disk at the defined quality
   if Qacc > -1:
      im.save(filename, format="JPEG", quality=Qacc)
   else:
      print("ERROR: No acceptble quality factor found", file=sys.stderr)

################################################################################
# main
################################################################################

# Load sample image
im = Image.open('/Users/mark/sample/images/lena.png')

# Save at best quality under 100,000 bytes
JPEGSaveWithTargetSize(im, "result.jpg", 100000)

If I run that as is, with target size of 100,000 bytes, I get:

[email protected]   1 mark  staff     96835 11 Sep 18:21 result.jpg

If I change the target size to 50,000 bytes, I get:

[email protected]   1 mark  staff     49532 11 Sep 18:26 result.jpg

Keywords: Python, PIL, Pillow, JPEG, quality, quality setting, max size, maximum size, image, image processing, binary search.

@moomoochen 2018-09-12 03:21:07

I got an error from your else statement, "ERROR: No acceptble quality factor found" What did I do wrong?

@Mark Setchell 2018-09-12 06:40:57

I can't tell for sure without seeing your image and the target size you specified. If you tried to reduce, say, an 8,000x6,000 pixel image to 5,000 bytes it will have had difficulties. Please share your image and target size, or try increasing the target size to give it a better chance of success.

@Mark Setchell 2018-09-20 15:54:55

Can you clarify what size (in pixels) of image you tried to compress with this please and what target size you specified - because I have tried it successfully on many files.

@moomoochen 2018-09-25 01:39:08

sorry for my late response, may I know what IDE you're using? and what OS you're using? Thank you so much :)

@Mark Setchell 2018-09-25 06:20:18

I don't use an IDE, I just type the code into an editor (vi, not that it makes any difference) and save it and run it. I tested the code on a Mac and under debian. You know the formatting (indentation) is critical, don't you?

Related Questions

Sponsored Content

34 Answered Questions

[SOLVED] How do I sort a dictionary by value?

42 Answered Questions

[SOLVED] How do I merge two dictionaries in a single expression?

61 Answered Questions

[SOLVED] How do you split a list into evenly sized chunks?

28 Answered Questions

[SOLVED] How do I check if a list is empty?

  • 2008-09-10 06:20:11
  • Ray Vega
  • 2553174 View
  • 3235 Score
  • 28 Answer
  • Tags:   python list

37 Answered Questions

[SOLVED] How do I check whether a file exists without exceptions?

21 Answered Questions

[SOLVED] How do I list all files of a directory?

  • 2010-07-08 19:31:22
  • duhhunjonn
  • 3769153 View
  • 3474 Score
  • 21 Answer
  • Tags:   python directory

18 Answered Questions

[SOLVED] CSS Display an Image Resized and Cropped

13 Answered Questions

[SOLVED] CSS Image size, how to fill, not stretch?

  • 2012-08-01 10:43:22
  • Mahdi Ghiasi
  • 708623 View
  • 382 Score
  • 13 Answer
  • Tags:   css image

43 Answered Questions

25 Answered Questions

[SOLVED] How can I safely create a nested directory?

Sponsored Content