La_haine
La_haine

Reputation: 349

Using PIL (Pillow) and Image but keeping a good resolution

I'm using PIL to resize my images. Most of them are 640x480, some of them are bigger. Most of them are in png, but I have jpeg extension too. I want to resize all my images to be 32x32 pixels, but I noticed that the resolution seems to change after using PIL.

I found that is a typical question and It's often a problem that figure out when you are saving the image. I tried with different values of "quality", I read the documentation trying different parametres such as "subsampling" and trying both jpeg and png format.

Here is my code:

from PIL import Image

im = Image.open(os.path.join(my_path, file_name))
            img = im.resize((32, 32))
            if grey_scale is True:
                img = img.convert('L')  # to resize image in gray scale
            img.save(os.path.join(my_path, 
file_name[:file_name.index('.')] + '.jpg'), "JPEG", quality=100) 

Here I have my input image Original input image

Here I have the grainy output obtained with my code

enter image description here

How can I resize my images to be smaller, but keeping a very good resolution?

Upvotes: 3

Views: 8792

Answers (2)

Tarun Lalwani
Tarun Lalwani

Reputation: 146490

Reducing the size, you can't keep the image crisp, because you need pixels for those and you can't keep both

There are different filters you can use in this case. See the below code

from PIL import Image
import os
import PIL
filters = [PIL.Image.NEAREST, PIL.Image.BILINEAR, PIL.Image.BICUBIC,  PIL.Image.ANTIALIAS]
grey_scale = False
i = 0
for filter in filters:
    im = Image.open("./image.png")
    img = im.resize((32, 32), filter)
    if grey_scale is True:
        img = img.convert('L')  # to resize image in gray scale
    i = i + 1
    img.save("./" + str(i) + '.jpg', "JPEG", quality=100)

Results:

Nearest Bilinear Bicubic Antialias

Next, using resize you don't maintain the aspect ratio. So instead of using resize, use the thumbnail method which keeps aspect ratio as well

from PIL import Image
import os
import PIL
filters = [PIL.Image.NEAREST, PIL.Image.BILINEAR, PIL.Image.BICUBIC,  PIL.Image.ANTIALIAS]
grey_scale = False
i = 5
for filter in filters:
    im = Image.open("./image.png")
    img = im.thumbnail((32, 32), filter)
    img = im
    if grey_scale is True:
        img = img.convert('L')  # to resize image in gray scale
    i = i + 1
    img.save("./" + str(i) + '.jpg', "JPEG", quality=100)

Results:

Nearest Bilinear Bicubic AntiAlias

Upvotes: 2

Vasu Deo.S
Vasu Deo.S

Reputation: 1850

The sort of image transformation you want is not possible. As when you try to resize an raster image to a lower pixel dimensions, you have to either Downsample it, or not sample it at all(simple resize). Even though you may preserve the resolution (total no of pixels in an image) but still since a pixel can represent one color at a time (atleast in a sub-pixel based display like a monitor), and your final image only has 1024 of them, and the detail in the original image is far more then what could be represented by these number of pixels, this would always result in a considerably lower quality(pixelated image with artifacts) in the final image.

But this is not the general case, as it depends a lot on what sort of details are represented by the image. If the image is not complex (not contains a lot of color changes), then it can be resized to a considerably lower quality version of it without losing details.

746x338 dimension image

enter image description here

32x32 dimension version of previous image

enter image description here

There is almost no difference between both the images (except for their physical size), even though their dimension's are a lot different. The Reason being these are non-complex images containing same pixel value over a large range, which makes it easier to resize them without loss in detail.

Now if the same process is tried out on a complex image, like the one you gave in the question, the result would be an Pixelated image.

SOLUTION:-

  • You can either choose for a large dimension value in the final image (a lot more then 32x32) if you want to preserve the image quality.

  • Create a Vector equivalent of your image, which is resolution independent and can be resized to a larger/smaller physical size without affecting image quality.

P.S.:- Don't save a .png image with .jpgextension, as jpg is a lossy compression technique(for the most part), which in turn results in a lower quality final image, then the original even if no manipulation are made over it.

Upvotes: 4

Related Questions