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

标签 python django python-imaging-library

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

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

但它在 python3 中不起作用。我认为问题出在 strbyte 上。

有人建议使用 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)

但它发生错误:'_io.BytesIO' 对象没有属性 'len' --> output.len 在我的代码中发生错误。

我开始怀疑使用 BytesIO 而不是 StringIO 是否正确。

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

最佳答案

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

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

    if self.image:
        with Img.open(BytesIO(self.image.read())) as img:
            if img.mode != 'RGB':
                img = img.convert('RGB')

            img.thumbnail((self.image.width/1.5,self.image.height/1.5), Img.ANTIALIAS)
            with BytesIO() as output:
                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.getbuffer().nbytes, None
                )

    super().save(*args, **kwargs)

关于python - 我必须使用哪一个来读取 Django 中的图像,StringIO 或 BytesIO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39198531/

相关文章:

python - 循环 2 个列表以创建多个 sql 游标,每个游标中有 2 个变化的变量

python - Django开发服务器的容量

Python quantlib 示例?

django - 如何调试 Django PayPal IPN?

python - 如何在url中发送批量数据?

python - 将图像中的所有白色像素转换为黑色像素

python - 128x512 数组列表中的图像列表可提高效率

适用于 Windows 的 Python DBM 模块?

python - 无法构建使用 PEP 517 且无法直接安装的密码学轮子

python - 将 1 层图像转换为 3 层图像