Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to save pil cropped image to image field in django

I am trying to save a cropped image to a model. I am getting the following error:

Traceback (most recent call last):  File "/mypath/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response    response = wrapped_callback(request, *callback_args, **callback_kwargs)  File "/mypath/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 22, in _wrapped_view    return view_func(request, *args, **kwargs)  File "/mypath/views.py", line 236, in player_edit    player.save()  File "/mypath/lib/python2.7/site-packages/django/db/models/base.py", line 734, in save    force_update=force_update, update_fields=update_fields)  File "/mypath/lib/python2.7/site-packages/django/db/models/base.py", line 762, in save_base    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)  File "/mypath/lib/python2.7/site-packages/django/db/models/base.py", line 824, in _save_table    for f in non_pks]  File "/mypath/lib/python2.7/site-packages/django/db/models/fields/files.py", line 313, in pre_save    if file and not file._committed:  File "/mypath/lib/python2.7/site-packages/PIL/Image.py", line 512, in getattr    raise AttributeError(name) AttributeError: _committed

My view which handles the form submit looks like this:

if request.method == 'POST':
        form = PlayerForm(request.POST, request.FILES, instance=current_player)
        if form.is_valid():

            temp_image = form.cleaned_data['profile_image2']
            player = form.save()
            cropped_image = cropper(temp_image, crop_coords)
            player.profile_image = cropped_image
            player.save() 
            return redirect('player')

The crop function looks like this:

from PIL import Image
import Image as pil

    def cropper(original_image, crop_coords):

        original_image = Image.open(original_image)

        original_image.crop((0, 0, 165, 165))

        original_image.save("img5.jpg")

        return original_image

Is this correct process to save the cropped image to the model. If so, why am I getting the above error?

Thanks!

like image 569
Atma Avatar asked Dec 07 '15 18:12

Atma


2 Answers

The function should look like this:

# The crop function looks like this:

from PIL import Image

from django.core.files.base import ContentFile

def cropper(original_image, crop_coords):
      img_io = StringIO.StringIO()
      original_image = Image.open(original_image)
      cropped_img = original_image.crop((0, 0, 165, 165))
      cropped_img.save(img_io, format='JPEG', quality=100)
      img_content = ContentFile(img_io.getvalue(), 'img5.jpg')
      return img_content
like image 193
phourxx Avatar answered Oct 05 '22 03:10

phourxx


For Python version >= 3.5

from io import BytesIO, StringIO()

img_io = StringIO() # or use BytesIO() depending on the type

rest of the things works great with @phourxx answer

like image 24
M.A.K. Simanto Avatar answered Oct 05 '22 02:10

M.A.K. Simanto