3
django
アプリケーションでアップロードする前に画像ファイルを圧縮しようとしています。Django、StringIO、またはBytesIOで画像を読み取るのにどちらを使う必要がありますか?
私は素敵なコードスニペットのサイトが見つかりました:https://djangosnippets.org/snippets/10460/
をしかし、それはpython3
では動作しません。問題は約str
またはbyte
と思います。
誰かがStringIO
の代わりにBytesIO
を使用することをお勧めします。
私はこのように自分のコードを編集します。
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' object has no attribute 'len'
- 私のコードで>output.len
は、エラーが発生します。
私は、StringIO
の代わりにBytesIO
を使用するのが正しいことを疑うようになります。
また、私のコードを編集する方法も必要です。ありがとう。
あなたは([それはバッファ 最初だ取得]で 'BytesIO'オブジェクトのデータの長さを得ることができますhttps://docs.python.org/3/library/io.html#io.BytesIO.getbuffer )。次に 'len(buffer)'で長さを取得できます。また、バッファー 'view'を' buf.release() 'で解放して、' BytesIO'オブジェクトをクローズする必要があります( 何らかの理由でやっていないようです)。 – Sevanteri
バッファのサイズだけではなく、BytesIOオブジェクト全体のサイズが必要になるかもしれません。あなたは['sys.getsizeof'](http://stackoverflow.com/questions/26827055/python-how-to-get-iobytes-allocated-memory-length)でそれを得ることができます。 – Sevanteri
コードを修正するにはどうすればよいですか? – user3595632