I'm trying to compress the image file before uploading in my django
application.
I found nice code snippet site : https://djangosnippets.org/snippets/10460/
but It doesn't work in python3
. I think the problem is about str
or byte
.
Someone advise to use BytesIO
instead of StringIO
.
So, I edit my code like this.
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)
But it occurs an error : '_io.BytesIO' object has no attribute 'len'
--> output.len
in my code occurs an error.
I start to doubt that It is right way to use BytesIO
instead of StringIO
.
And need some helps how to edit my code, too. Thanks.
I modified the code to use the with
statement so there is no need to close the files yourself.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With