ImageOps.fit is blurring my image - python

I'm using ImageOps to resize and center-crop uploaded avatar images. The problem is, when I try to upload an image that is already the desired size, the uploaded image is blurred.
The relevant code:
avatar_size = (59,59)
#resized_im = im.resize(avatar_size, Image.ANTIALIAS) #This works! But doesn't crop.
formatted_im = ImageOps.fit(im, avatar_size, Image.ANTIALIAS, centering=(0.5,0.5))
formatted_im.save('foo.jpg', 'JPEG', quality=95)
So, when I upload a 59x59px image, the resulting upload on the server is blurred. Tried googling, reading the docs, and experimenting, but can't figure this out. Thanks for the help.

It is probably the antialiasing which is causing the blur.
How about try:
avatar_size = (59,59)
method = Image.NEAREST if im.size == avatar_size else Image.ANTIALIAS
formatted_im = ImageOps.fit(im, avatar_size, method = method, centering = (0.5,0.5))
formatted_im.save('foo.jpg', 'JPEG', quality=95)

Related

Does anyone know how to convert an ico to a png using python?

This is my attempt:
import os
from PIL import Image
directory = r'../Icons/ico'
for filename in os.listdir(directory):
if filename.endswith(".ico"):
print(os.path.join(directory, filename))
img = Image.open(os.path.join(directory,filename))
sizes = img.info['sizes']
for i in sizes:
img.size = i
print(img.size)
size_in_string = str(img.size)
img.save('png/' + filename.strip('.ico') + size_in_string + '.png')
else:
continue
I'm afraid that this code is not grabbing the separate ico files and instead, grabbing the largest ico file and resizing it. Can someone please help me?
According to your title.
Here is how to convert a ico to png through python.
from PIL import Image
filename = 'image.ico'
img = Image.open(filename)
img.save('image.png')
#Optinally to save with size
icon_sizes = [...]
img.save('image.png', sizes=icon_sizes)
I am pretty sure you can adapt it in your code.
you can give a try to :
https://www.convertapi.com/ico-to-png
Code snippet is using ConvertAPI Python Client
convertapi.api_secret = '<YOUR SECRET HERE>'
convertapi.convert('png', {
'File': '/path/to/my_file.ico'
}, from_format = 'ico').save_files('/path/to/dir')
In addition, we do have a question in stackoverflow.com:
How to convert an .ICO to .PNG with Python?
or you can just change the end of the .ico file to .png

Resize images in python using PIL

I'm trying to resize a set of images, approximatively 366, so I created a script that I tested first on 3 and it was successful.
The issue is when I process the whole folder, it returns me this error :
resizeimage.imageexceptions.ImageSizeError: 'Image is too small, Image size : (275, 183), Required size : (399, 399)'
My script is supposed to iterate an entire folder, resize images then store the output files in another folder:
import os
from PIL import Image
from resizeimage import resizeimage
path = "/Users/sigc2sige/PycharmProjects/helloworld/photos"
size = (399, 399)
for file in os.listdir(path):
with open('/Users/sigc2sige/PycharmProjects/helloworld/photos/'+file, 'r+b') as f:
with Image.open(f) as image:
cover = resizeimage.resize_cover(image, size, Image.ANTIALIAS)
cover.save('/Users/sigc2sige/PycharmProjects/helloworld/photos_2/'+file, image.format)
I did use this instruction:
thumb = ImageOps.fit(image, size, Image.ANTIALIAS) but I believe that it crops images instead of resizing them.
If you have any ideas about how to solve this issue, it would be great.
Downsampling an image (making it smaller) is one thing, and upsampling (making it bigger) is another thing. If you want to downsample, ANTIALIAS is a good choice, if you want to upsample, there are other filters you could use.
import os
from PIL import Image
from resizeimage import resizeimage
path = "/Users/sigc2sige/PycharmProjects/helloworld/photos"
size = (399, 399)
for file in os.listdir(path):
with open('/Users/sigc2sige/PycharmProjects/helloworld/photos/'+file, 'r+b') as f:
with Image.open(f) as image:
if (image.size) >= size:
cover = resizeimage.resize_cover(image, size, Image.ANTIALIAS)
cover.save('/Users/sigc2sige/PycharmProjects/helloworld/photos_2/'+file, image.format)
else:
cover = image.resize(size, Image.BICUBIC).save('/Users/sigc2sige/PycharmProjects/helloworld/photos_2/'+file, image.format)

PIL - saving image as .jpg not working

I'm trying to overwrite save() method of the model to resize images. Every format works, except when saving a .jpg image. It's not saving images with .jpg extension.
I read the Pillow documentation and there's no JPG format.
class Business(models.Model):
photo = models.ImageField(_('photo'), storage=OverwriteStorage(),
upload_to=image_upload_to, blank=True, null=True)
def save(self, **kwargs):
"""
Changing dimensions of images if they are to big.
Set max height or width to 800px depending on the image is portrait or landscape.
"""
# Opening the uploaded image
im = Image.open(self.photo)
print(im)
output = BytesIO()
# set the max width or height
im.thumbnail((800, 800))
# find the ext of the file
ext = self.photo.name.split('.')[1].upper()
if ext in {'JPEG', 'PNG', 'GIF', 'TIFF'}:
# after modifications, save it to the output
im.save(output, format=ext, quality=100)
output.seek(0)
# change the imagefield value to be the newley modifed image value
self.photo = InMemoryUploadedFile(output, 'ImageField', "%s.jpg" % self.photo.name.split('.')[0],
'image/jpeg', sys.getsizeof(output), None)
super(User, self).save()
I don't know what I am missing here.
And what's the best way to do this on a custom User model. Using a signal, overwriting ImageField or ...
Any help is appreciated :)
You handled extension JPEG, but not JPG.
You may handle it simply with something like that before your if:
if ext == 'JPG':
ext = 'JPEG'
Important: You can not save the files as a .jpg
You must use another extension such as .jpeg
Example:
You have to use the Image object you import
from PIL import Image
def image_ex():
imagefile = 'images/original-image.jpg'
new_name = os.path.splitext('{}'.format(filename))[0]+'.jpeg'
Image.open(imagefile).rotate(270).filter(ImageFilter.DETAIL).save(new_name)
image_ex()
That works. Just remember dont save as a .jpg file extensions.

How can I capture a picture from webcam and send it via flask

I want to send an Image object in a flask response but it gives me an error. I tried also an approach with StringIO.
image = Image.open("./static/img/test.jpg")
return send_file(image, mimetype='image/jpeg')
This is just a test case. So the major problem is to capture an image from /dev/video0 and sent it (ideally without temporary storing on disk) to the client. I use v4l2capture for that. The test picture should also work if you may have a better solution for that task.
import select
import v4l2capture
video = v4l2capture.Video_device("/dev/video0")
size_x, size_y = video.set_format(1280, 1024)
video.create_buffers(1)
video.queue_all_buffers()
video.start()
select.select((video,), (), ())
image_data = video.read()
video.close()
image = Image.fromstring("RGB", (size_x, size_y), image_data)
Thanks.
EDIT
Works now. Better solutions as v4l2capture are welcome...
Did it with.
image = Image.open("./static/img/test.jpg")
img_io = StringIO()
image.save(img_io, 'JPEG', quality=70)
img_io.seek(0)
return send_file(img_io, mimetype='image/jpeg')

Upload Image To Imgur After Resizeing In PIL

I am writing a script which will get an image from a link. Then the image will be resized using the PIL module and the uploaded to Imgur using pyimgur. I dont want to save the image on disk, instead manipulate the image in memory and then upload it from memory to Imgur.
The Script:
from pyimgur import Imgur
import cStringIO
import requests
from PIL import Image
LINK = "http://pngimg.com/upload/cat_PNG106.png"
CLIENT_ID = '29619ae5d125ae6'
im = Imgur(CLIENT_ID)
def _upload_image(img, title):
uploaded_image = im.upload_image(img, title=title)
return uploaded_image.link
def _resize_image(width, height, link):
#Retrieve our source image from a URL
fp = requests.get(link)
#Load the URL data into an image
img = cStringIO.StringIO(fp.content)
im = Image.open(img)
#Resize the image
im2 = im.resize((width, height), Image.NEAREST)
#saving the image into a cStringIO object to avoid writing to disk
out_im2 = cStringIO.StringIO()
im2.save(out_im2, 'png')
return out_im2.getvalue()
When I run this script I get this error: TypeError: file() argument 1 must be encoded string without NULL bytes, not str
Anyone has a solution in mind?
It looks like the same problem as this, and the solution is to use StringIO.
A common tip for searching such issues is to search using the generic part of the error message/string.

Categories