Python not resizing height of an image - python

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.

Related

python pillow when I open a portrait (height greater than width) image, the image is rotated ccw 90 degrees

When I open an image which is higher than width (portrait), the image
is rotated 90 degrees ccw.
from PIL import ImageTk, Image
from pathlib import Path
wd = Path.cwd()
fn = wd / 'sample.jpg'
path = str(fn)
img = Image.open(path)
img.show()
A couple of things. Apparently show saves the image as a .png temp file, and that save loses the orientation information that is in the exif data of the jpg image. I also had trouble with rotate. There is some inconsistency in the Pillow image functions. e.g. thumbnail updates the supplied image and return None.
rotate rotates the image and returns the changed image.
fimage.thumbnail((700,700), Image.ANTIALIAS)
simage = fimage.rotate(270)
# update. Transpose will use EXIF data if available to
# rotate the image to the correct orientation
from PIL import ImageOps
img = ImageOps.exif_transpose(img)
Reference: https://pillow.readthedocs.io/en/stable/reference/ImageOps.html#PIL.ImageOps.exif_transpose

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 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

Programmatically change image resolution

I have calculated that if I want my generated image to be A4 size # 600dpi for print purpose, it needs to be 7016x4961px # 72dpi. So, I generate it programmatically, then test it in Photoshop and it seems to be fine so if I resize it, it gets proper size and resolution
.
What I wonder about is if it's possible to make this resizing programmatically, preferably with PIL, but not necessarily with it. I need to make it higher DPI.
If you have generated your image 7016 x 4961 px, it is already A4 at 600 dpi. So you don't need to resize it, you just have to set resolution information in file.
You can do it with PIL:
from PIL import Image
im = Image.open("test.png")
im.save("test-600.png", dpi=(600,600))
This code will resize a PNG image into 7016x4961 with PIL:
size = 7016, 4961
im = Image.open("my_image.png")
im_resized = im.resize(size, Image.ANTIALIAS)
im_resized.save("my_image_resized.png", "PNG")
Perhaps a better approach would be to make your canvas x times bigger prior to printing, where x is a factor you have to figure out (7016x4961 in size for this particular image).
Here's how you can resize by batch (per folder) and skip other file types and Mac system files like .DS_Store
from PIL import Image
import os
Image.MAX_IMAGE_PIXELS = None
path = "./*your-source-folder*"
resize_ratio = 2 # where 0.5 is half size, 2 is double size
def resize_aspect_fit():
dirs = os.listdir(path)
for item in dirs:
print(item)
if item == '.DS_Store':
continue
if item == 'Icon\r':
continue
if item.endswith(".mp4"):
continue
if item.endswith(".txt"):
continue
if item.endswith(".db"):
continue
if os.path.isfile(path+item):
image = Image.open(path+item)
file_path, extension = os.path.splitext(path+item)
new_image_height = int(image.size[0] / (1/resize_ratio))
new_image_length = int(image.size[1] / (1/resize_ratio))
image = image.resize((new_image_height, new_image_length), Image.ANTIALIAS)
image.save("./*your-output-folder*/" + item)
resize_aspect_fit()

PIL Image.resize() not resizing the picture

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()

Categories

Resources