0

モデルがディスクに保存される前に ImageField をスケーリングしたいのですが、どうにかして読み取り不能な画像を出力してしまいます。目標は、ディスクに保存せずにスケーリングすることです。

これはこれまでの私の試みです:

IMAGE_MAX_SIZE = 800, 800
class Picture(models.Model):
    ...
    image = models.ImageField(upload_to='images/%Y/%m/%d/')

    # img is a InMemoryUploadedFile, received from a post upload
    # removing the scale function results in a readable image
    def set_image(self, img):
        self.image = img
        self.__scale_image()

    def __scale_image(self):
        img = Image.open(StringIO(self.image.read()))
        img.thumbnail(IMAGE_MAX_SIZE, Image.ANTIALIAS)
        imageString = StringIO()
        img.save(imageString, img.format)
        self.image.file = InMemoryUploadedFile(imageString, None, self.image.name, self.image.file.content_type, imageString.len, None)

エラーにはなっていませんが、結果の画像を正しく表示できません。これを修正する方法はありますか?

ありがとうサイモン

4

2 に答える 2

1

私は近くにいましたが、そこまでではありませんでした。この関数は正常に機能し、スケーリング中のどの時点でもイメージはディスクに保存されません。

IMAGE_MAX_SIZE = 800, 800
class Picture(models.Model):
    ...
    image = models.ImageField(upload_to='images/%Y/%m/%d/')

    # img is a InMemoryUploadedFile, received from a post upload
    def set_image(self, img):
        self.image = img
        self.__scale_image(self.image, IMAGE_MAX_SIZE)

    def __scale_image(self, image, size):
        image.file.seek(0) # just in case
        img = Image.open(StringIO(image.file.read()))
        img.thumbnail(size, Image.ANTIALIAS)
        imageString = StringIO()
        img.save(imageString, img.format)

        # for some reason content_type is e.g. 'images/jpeg' instead of 'image/jpeg'
        c_type = image.file.content_type.replace('images', 'image')
        imf = InMemoryUploadedFile(imageString, None, image.name, c_type, imageString.len, None)
        imf.seek(0)
        image.save(
                image.name,
                imf,
                save=False
            )
于 2012-11-09T00:21:20.210 に答える
0

sorl-thubnail を使用することをお勧めします。

于 2012-11-08T12:22:43.400 に答える