我必须使用哪一个来读取 Django、StringIO 或 BytesIO 中的图像?

use*_*632 5 python django python-imaging-library

我正在尝试在上传到我的django应用程序之前压缩图像文件。

我找到了不错的代码片段站点:https : //djangosnippets.org/snippets/10460/

但它在python3. 我认为问题是关于stror 的byte

有人建议使用BytesIO而不是StringIO.

所以,我像这样编辑我的代码。

from django.db import models
from django.core.urlresolvers import reverse
from django.utils import timezone
from django.utils.text import slugify
from django.core.files.uploadedfile import InMemoryUploadedFile

from PIL import Image as Img
from io import StringIO, BytesIO

def upload_location(instance, file_name):
    return "{}/{}/{}/{}".format(
        "album",
        instance.day,
        instance.week,
        file_name
    )


class Album(models.Model):

    DAYS = (
        ('Sun', '???'),
        ('Mon', '???'),
    )
    name = models.CharField(max_length=50)
    description = models.CharField(max_length=100, blank=True)
    image = models.ImageField(upload_to=upload_location)
    day = models.CharField(max_length=3, choices=DAYS)
    week = models.IntegerField()
    slug = models.SlugField(unique=True, allow_unicode=True)
    date = models.DateField()

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['day', 'week']

    def __str__(self):
        return "{} - {}??".format(self.get_day_display(), self.week)

    def get_absolute_url(self):
        return reverse(
            "album:album_detail",
            kwargs={
                "slug": self.slug
            }
        )

    def save(self, *args, **kwargs):
        if not self.id:
            self.slug = self.slug + "??"

        if self.image:
            img = Img.open(BytesIO(self.image.read()))
            if img.mode != 'RGB':
                img = img.convert('RGB')
            img.thumbnail((self.image.width/1.5,self.image.height/1.5), Img.ANTIALIAS)
            output = BytesIO()
            img.save(output, format='JPEG', quality=70)
            output.seek(0)
            self.image= InMemoryUploadedFile(
                output,'ImageField',
                "%s.jpg" %self.image.name.split('.')[0],
                'image/jpeg',
                output.len, None
            )
        super().save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

但它发生了一个错误:'_io.BytesIO' object has no attribute 'len'-->output.len在我的代码中发生了一个错误。

我开始怀疑这是使用BytesIO而不是StringIO.

也需要一些帮助来编辑我的代码。谢谢。

Sev*_*eri 3

我修改了代码以使用该with语句,因此无需自己关闭文件。

\n\n
def save(self, *args, **kwargs):\n    if not self.id:\n        self.slug = self.slug + "\xec\xa3\xbc\xec\xb0\xa8"\n\n    if self.image:\n        with Img.open(BytesIO(self.image.read())) as img:\n            if img.mode != \'RGB\':\n                img = img.convert(\'RGB\')\n\n            img.thumbnail((self.image.width/1.5,self.image.height/1.5), Img.ANTIALIAS)\n            with BytesIO() as output:\n                img.save(output, format=\'JPEG\', quality=70)\n                output.seek(0)\n                self.image = InMemoryUploadedFile(\n                    output,\'ImageField\',\n                    "%s.jpg" %self.image.name.split(\'.\')[0],\n                    \'image/jpeg\',\n                    output.getbuffer().nbytes, None\n                )\n\n    super().save(*args, **kwargs)\n
Run Code Online (Sandbox Code Playgroud)\n