getting Cannot identify image file when trying to create thumbnail in django

Posted by Mo J. Mughrabi on Stack Overflow See other posts from Stack Overflow or by Mo J. Mughrabi
Published on 2012-11-29T15:28:45Z Indexed on 2012/12/01 17:04 UTC
Read the original article Hit count: 210

Am trying to create a thumbnail in django, am trying to build a custom class specifically to be used for generating thumbnails. As following

from StringIO import StringIO
from PIL import Image

class Thumbnail(object):
    source  = ''
    size    = (50, 50)
    output = ''

    def __init__(self):
        pass

    @staticmethod
    def load(src):
        self        = Thumbnail()
        self.source = src

        return self

    def generate(self, size=(50, 50)):
        if not isinstance(size, tuple):
            raise Exception('Thumbnail class: The size parameter must be an instance of a tuple.')

        self.size   = size
        # resize properties
        box = self.size
        factor = 1
        fit = True
        image = Image.open(self.source)
        # Convert to RGB if necessary
        if image.mode not in ('L', 'RGB'): image = image.convert('RGB')
        while image.size[0]/factor > 2*box[0] and image.size[1]*2/factor > 2*box[1]:
            factor *=2
        if factor > 1:
            image.thumbnail((image.size[0]/factor, image.size[1]/factor), Image.NEAREST)

        #calculate the cropping box and get the cropped part
        if fit:
            x1 = y1 = 0
            x2, y2 = image.size
            wRatio = 1.0 * x2/box[0]
            hRatio = 1.0 * y2/box[1]
            if hRatio > wRatio:
                y1 = int(y2/2-box[1]*wRatio/2)
                y2 = int(y2/2+box[1]*wRatio/2)
            else:
                x1 = int(x2/2-box[0]*hRatio/2)
                x2 = int(x2/2+box[0]*hRatio/2)
            image = image.crop((x1,y1,x2,y2))

        #Resize the image with best quality algorithm ANTI-ALIAS
        image.thumbnail(box, Image.ANTIALIAS)

        # save image to memory
        temp_handle = StringIO()
        image.save(temp_handle, 'png')
        temp_handle.seek(0)

        self.output = temp_handle

        return self

    def get_output(self):
        return self.output.read()

the purpose of the class is so i can use it inside different locations to generate thumbnails on the fly. The class works perfectly, I've tested it directly under a view.. I've implemented the thumbnail class inside the save method of the forms to resize the original images on saving.

in my design, I have two fields for thumbnails. I was able to generate one thumbnail, if I try to generate two it crashes and I've been stuck for hours not sure whats the problem.

Here is my model

class Image(models.Model):
    article         = models.ForeignKey(Article)
    title           = models.CharField(max_length=100, null=True, blank=True)
    src             = models.ImageField(upload_to='publication/image/')
    r128            = models.ImageField(upload_to='publication/image/128/', blank=True, null=True)
    r200            = models.ImageField(upload_to='publication/image/200/', blank=True, null=True)

    uploaded_at     = models.DateTimeField(auto_now=True)

Here is my forms

class ImageForm(models.ModelForm):
    """

    """
    class Meta:
        model = Image
        fields = ('src',)


    def save(self, commit=True):
        instance = super(ImageForm, self).save(commit=True)

        file = Thumbnail.load(instance.src)

        instance.r128 = SimpleUploadedFile(
                    instance.src.name,
                    file.generate((128, 128)).get_output(),
                    content_type='image/png'
                )


        instance.r200 = SimpleUploadedFile(
            instance.src.name,
            file.generate((200, 200)).get_output(),
            content_type='image/png'
        )

        if commit:
            instance.save()
        return instance

the strange part is, when i remove the line which contains instance.r200 in the form save. It works fine, and it does the thumbnail and stores it successfully. Once I add the second thumbnail it fails..

Any ideas what am doing wrong here?

Thanks

Update:

I tried earlier doing the following but I still got the same error

class ImageForm(models.ModelForm):
    """

    """
    class Meta:
        model = Image
        fields = ('src',)


    def save(self, commit=True):
        instance = super(ImageForm, self).save(commit=True)


        instance.r128 = SimpleUploadedFile(
                    instance.src.name,
                    Thumbnail.load(instance.src).generate((128, 128)).get_output(),
                    content_type='image/png'
                )


        instance.r200 = SimpleUploadedFile(
            instance.src.name,
            Thumbnail.load(instance.src).generate((200, 200)).get_output(),
            content_type='image/png'
        )

        if commit:
            instance.save()
        return instance

© Stack Overflow or respective owner

Related posts about python

Related posts about django