PIL Image.resize() not resizing the picture - python

I have some strange problem with PIL not resizing the image.
from PIL import Image
img = Image.open('foo.jpg')
width, height = img.size
ratio = floor(height / width)
newheight = ratio * 150
img.resize((150, newheight), Image.ANTIALIAS)
img.save('mugshotv2.jpg', format='JPEG')
This code runs without any errors and produces me image named mugshotv2.jpg in correct folder, but it does not resize it. It does something to it, because the size of the picture drops from 120 kb to 20 kb, but the dimensions remain the same.
Perhaps you can also suggest way to crop images into squares with less code. I kinda thought that Image.thumbnail does it, but what it did was that it scaled my image to 150 px by its width, leaving height 100px.

resize() returns a resized copy of an image. It doesn't modify the original. The correct way to use it is:
from PIL import Image
#...
img = img.resize((150, newheight), Image.ANTIALIAS)
source
I think what you are looking for is the ImageOps.fit function. From PIL docs:
ImageOps.fit(image, size, method, bleed, centering) => image
Returns a sized and cropped version of
the image, cropped to the requested
aspect ratio and size. The size
argument is the requested output size
in pixels, given as a (width, height)
tuple.

[Update]
ANTIALIAS is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.LANCZOS instead.image.resize((100,100),Image.ANTIALIAS)

Today you should use something like this:
from PIL import Image
img = Image.open(r"C:\test.png")
img.show()
img_resized = img.resize((100, 100), Image.Resampling.LANCZOS)
img_resized.show()

Related

Fill image up to a size with Python

I am writing a handwriting recognition app and my inputs have to be of a certain size (128x128). When I detect a letter it looks like this:
That image for instance has a size of 40x53. I want to make it 128x128, but simply resizing it lowers the quality especially for smaller images. I want to somehow fill the rest up to 128x128 with the 40x53 in the middle. The background color should also stay relatively the same. I am using Python's opencv but I am new to it. How can I do this, and is it even possible?
Here you can get what you have asked using outputImage. Basically I have added a border using copyMakeBorder method. You can refer this for more details. You have to set the color value as you want in the value parameter. For now it is white [255,255,255].
But I would rather suggest you to resize the original image, seems like it is the better option than what you have asked. Get the image resized you can use resized in the following code. For your convenience I have added both methods in this code.
import cv2
import numpy as np
inputImage = cv2.imread('input.jpg', 1)
outputImage = cv2.copyMakeBorder(inputImage,37,38,44,44,cv2.BORDER_CONSTANT,value=[255,255,255])
resized = cv2.resize(inputImage, (128,128), interpolation = cv2.INTER_AREA)
cv2.imwrite('output.jpg', outputImage)
cv2.imwrite('resized.jpg', resized)
I believe you want to scale your image.
This code might help:
import cv2
img = cv2.imread('name_of_image', cv2.IMREAD_UNCHANGED)
# Get original size of image
print('Original Dimensions: ',img.shape)
# Percentage of the original size
scale_percent = 220
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)
# Resize/Scale the image
resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
# The new size of the image
print('Resized Dimensions: ',resized.shape)
cv2.imshow("Resized image", resized)
cv2.waitKey(0)
cv2.destroyAllWindows()

Resize images to very small n x n dimensions

I am resizing my images to 50 x 50 in python. Skimage transform and PIL thumbnail both resize the image while preserving the aspect ratio.
Whats the other way to do it?
I have tried:
For PIL thumbnail,
im.thumbnail((50,50),Image.ANTIALIAS)
This gives me a (42,50) image not a (50,50) image.
For skimage.transform
image = skimage.transform.resize(image, (50, 50))
It returns a completely distorted image.
Use im.resize((50,50), Image.ANTIALIAS)
To resize to fixed size while maintaining aspect ratio and cropping to fit, use PIL.ImageOps.fit(image,size)
import PIL.ImageOps
import PIL.Image
impath = '1-True Mountain Covered with Cloud.jpg'
im = PIL.Image.open(impath)
display(im)
imfit = PIL.ImageOps.fit(im, (64,64))
display(imfit)

Python not resizing height of an image

I want to resize some images and here is my code.
import os
from PIL import Image
size = 300, 300
for f in os.listdir('.'):
if f.endswith('.png'):
i = Image.open(f)
fn, fext = os.path.splitext(f)
i.thumbnail(size, Image.ANTIALIAS)
i.save('output/{}{}'.format(fn, fext))
The code is working fine and it resizes all my image to a width of 300px, but the height did not resize.
Can anyone tell me why?
Image.thumbnail() is designed to keep the aspect ratio of the original image. If you want the output image to be exactly 300x300 px, use Image.resize() instead.

Python Resize image with ratio of maximum side of the image

I am very new in Python and this is going to be a very basic question.I have a website which is image based and i am developing it using Django.Now i want to resize the image or you can say i want to minimize the size of the images.There are different size of images are avaible,some images are largest in width,some images are largest in height and i want to resize images without changing there shape.
Here are some example what dimensions images are using in my website.
Here the First image is largest in width and the second image is largest in height and they are really big in Dimension.so they need to be resized or rather these images are need to be minimized in size.So i have used the PIL as below.
from PIL import Image,ImageDraw, ImageFont, ImageEnhance
def image_resize(request,image_id):
photo = Photo.objects.get(pk=image_id)
img = Image.open(photo.photo.file)
image = img.resize((1000, 560), Image.ANTIALIAS)
image.save()
so this function returns all the images with width of 1000 and height of 560.But i don't want to resize all the images with same width and height,rather i want to resize each images maintaining there own shape. That is there shape will be same but the images will be resized.How can i do this? i am really new in python.
Do you want to have all images with same width 1000? Try this code. It will resize to at most 1000 as width (if the image's width is less than 1000, nothing changes)
def image_resize(request,image_id):
photo = Photo.objects.get(pk=image_id)
image = Image.open(photo.photo.file)
(w,h) = image.size
if (w > 1000):
h = int(h * 1000. / w)
w = 1000
image = image.resize((w, h), Image.ANTIALIAS)
image.save()
I recall doing this sometime back without any problem except that I used thumbnail method rather than resize. Try it. You need not assign img to image. You can process img and save the same.
# open img
img.thumbnail((1000,560), Image.ANTIALIAS)
# save img

Does Python PIL resize maintain the aspect ratio?

Does PIL resize to the exact dimensions I give it no matter what? Or will it try to keep the aspect ratio if I give it something like the Image.ANTIALIAS argument?
Yes it will keep aspect ratio using thumbnail method:
image = Image.open(source_path)
image.thumbnail((500,500), Image.ANTIALIAS)
image.save(dest_path, "JPEG")
How do I resize an image using PIL and maintain its aspect ratio?
Image.resize from PIL will do exactly as told. No behind scenes aspect ratio stuff.
Recent Pillow version (since 8.3) have the following method to have an image resized to fit in given box with keeping aspect ratio.
image = ImageOps.contain(image, (2048,2048))
Yes. the thumbnail() method is what is needed here... One thing that hasn't been mentioned in this or other posts on the topic is that 'size' must be either a list or tuple. So, to resize to a maximum dimension of 500 pixels, you would call:
image.thumbnail((500,500), Image.ANTIALIAS)
See also this post on the subject:
How do I resize an image using PIL and maintain its aspect ratio?
No, it does not. But you can do something like the following:
im = PIL.Image.open("email.jpg"))
width, height = im.size
im = im.resize((width//2, height//2))
Here the height and width are divided by the same number, keeping the same aspect ratio.
Okay, so this requires a couple of lines of code to get what you want.
First you find the ratio, then you fix a dimension of the image that you want (height or width). In my case, I wanted height as 100px and let the width adjust accordingly, and finally use that ratio to find new height or new width.
So first find the dimensions:
width, height = logo_img.size
ratio = width / height
Then, fix one of the dimension:
new_height = 100
Then find new width for that height:
new_width = int(ratio * new_height)
logo_img = logo_img.resize((new_width, new_height))
It depends on your demand, if you want you can set a fixed height and width or if you want you can resize it with aspect-ratio.
For the aspect-ratio-wise resize you can try with the below codes :
To make the new image half the width and half the height of the original image:
from PIL import Image
im = Image.open("image.jpg")
resized_im = im.resize((round(im.size[0]*0.5), round(im.size[1]*0.5)))
#Save the cropped image
resized_im.save('resizedimage.jpg')
To resize with fixed width and ratio wise dynamic height :
from PIL import Image
new_width = 300
im = Image.open("img/7.jpeg")
concat = int(new_width/float(im.size[0]))
size = int((float(im.size[1])*float(concat)))
resized_im = im.resize((new_width,size), Image.ANTIALIAS)
#Save the cropped image
resized_im.save('resizedimage.jpg')
Recent versions of Pillow have some useful methods in PIL.ImageOps.
Depending on exactly what you're trying to achieve, you may be looking for one of these:
ImageOps.fit(image, size [, …]) (docs) – resizes your image, maintaining its aspect ratio, and crops it to fit the given size
ImageOps.contain(image, size [, …]) (docs) – resizes your image, maintaining its aspect ratio, so that it fits within the given size
One complete example:
import PIL.Image
class ImageUtils(object):
#classmethod
def resize_image(cls, image: PIL.Image.Image, width=None, height=None) -> PIL.Image.Image:
if height is None and width is not None:
height = image.height * width // image.width
elif width is None and height is not None:
width = image.width * height // image.height
elif height is None and width is None:
raise RuntimeError("At lease one of width and height must be present")
return image.resize((width, height))
def main():
ImageUtils.resize_image(PIL.Image.open("old.png"), width=100).save("new.png")
if __name__ == '__main__':
main()
I think following is the easiest way to do:
Img1 = img.resize((img.size),PIL.Image.ANTIALIAS)

Categories

Resources