sajid
sajid

Reputation: 883

Django throwing IO Error when trying to convert .gif file to .jpeg

I am newbie in python world. For a project (using django) I am using PIL library to convert .gif file to .jpg file. But when the save method of the model is run it throws 'IOError at ... cannot write mode P as JPEG'

Here is my Model class. Please suggest me a solution. Thanks in advance.

class ImageArtwork(models.Model):
    filepath = 'art_images/'
    artwork = models.ForeignKey(Artwork, related_name='images')
    artwork_image = models.ImageField(_(u"Dieses Bild hinzufügen: "), upload_to=filepath)
    image_medium = models.CharField(max_length=255, blank=True)
    image_thumb = models.CharField(max_length=255, blank=True)
    uploaded_at = models.DateTimeField(auto_now_add=True)

    def get_thumb(self):
        return "/media/%s" % self.image_thumb

    def get_medium(self):
        return "/media/%s" % self.image_medium

    def get_original(self):
        return "/media/%s" % self.artwork_image

    def save(self):
        sizes = {'thumbnail': {'height': 50, 'width': 50}, 'medium': {'height': 300, 'width': 300}, }

        # Check if the number of images for the artwork has already reached maximum limit

        if ImageArtwork.objects.filter(artwork=self.artwork).count() < 6:
            super(ImageArtwork, self).save()
            photopath = str(self.artwork_image.path)        # this returns the full system path to the original file
            im = Image.open(photopath)      # open the image using PIL

            # pull a few variables out of that full path
            extension = photopath.rsplit('.', 1)[1]     # the file extension
            filename = photopath.rsplit('/', 1)[1].rsplit('.', 1)[0]  # the file name only (minus path or extension)
            fullpath = photopath.rsplit('/', 1)[0]      # the path only (minus the filename.extension)

            # use the file extension to determine if the image is valid before proceeding
            if extension.lower() not in ['jpg', 'jpeg', 'gif', 'png']:
                return
            im = ImageOps.fit(im, (sizes['medium']['width'], sizes['medium']['height']), Image.ANTIALIAS)       # create medium image
            medname = filename + "_" + str(sizes['medium']['width']) + "x" + str(sizes['medium']['height']) + ".jpg"
            im.save(fullpath + '/' + medname)
            self.image_medium = '/media/' + self.filepath + medname
            im = ImageOps.fit(im, (sizes['thumbnail']['width'], sizes['thumbnail']['height']), Image.ANTIALIAS)     # create thumbnail
            thumbname = filename + "_" + str(sizes['thumbnail']['width']) + "x" + str(
                sizes['thumbnail']['height']) + ".jpg"
            im.save(fullpath + '/' + thumbname)
            self.image_thumb = '/media/' + self.filepath + thumbname
            super(ImageArtwork, self).save()

        else:
            pass

Upvotes: 1

Views: 177

Answers (1)

dhke
dhke

Reputation: 15398

cannot write mode P as JPEG

That's not a django problem, it's an imaging library constraint.

P stands for paletted. PIL tries to preserve the colour mode from the original image when writing the JPEG. Since JPEG only supports "TrueColor" (i.e. RGB) images, you get this error when converting a (paletted) GIF file.

Always convert the image to RGB when saving to JPEG:

im.convert('RGB').save(fullpath + '/' + medname)

Upvotes: 4

Related Questions