如何使用 Django 调整用户图像的大小并上传到 Amazon S3?
How to use Django to resize a user's image and upload to Amazon S3?
我无法将两个想法放在一起,调整 models.ImageField
中的图像大小(如果我不尝试同时上传到我的 Amazon S3 存储桶,效果很好)并将图像上传到我的 Amazon S3桶)。
我的模特:
from django.db import models
from django.conf import settings
from storages.backends.s3boto import S3BotoStorage
from django.core.files.storage import default_storage as storage
import datetime
from PIL import Image
import math
class Artwork(models.Model):
title = models.CharField(max_length=200)
# other fields...
full_image_large = models.ImageField(storage=S3BotoStorage(location='img'))
full_image = models.ImageField(storage=S3BotoStorage(location='img'), editable=False)
thumbnail_image = models.ImageField(storage=S3BotoStorage(location='img'), editable=False)
def __str__(self):
return self.title
def save(self):
super(Artwork, self).save()
image = Image.open(self.full_image_large, 'r')
(w, h) = image.size
for width, target in zip([900.0, 350.0, 120.0],
[self.full_image_large,
self.full_image,
self.thumbnail_image]):
r = width/w
im = image.resize((int(math.floor(r*w)),
int(math.floor(r*h))),
Image.ANTIALIAS)
im.save(target, format='JPEG')
所以 full_image_large
是可编辑的,用户可以上传。我想要将这张照片调整为 900px 的宽度,无论其大小如何(保持纵横比)。然后,我还尝试将同一张照片的大小调整为 full_image
,宽度应为 350px。最后,我试图将同一张照片的大小调整为 thumbnail_image
,宽度应为 120px。
当我转到站点的管理员 url 并保存对象时,出现以下错误。
The 'full_image' attribute has no file associated with it.
第一张图片上传到 Amazon S3(如果我注释掉对其他两张图片的引用)就好了,但没有调整大小。如果有人能以最简单的方式帮助我完成我正在做的事情,那将不胜感激。谢谢。注意:我正在使用 Python3。
我也尝试过使用 django-imagekit
但没有成功。
请尝试使用以下内容:
def save(self):
image = Image.open(self.full_image_large)
(w, h) = image.size
r900 = 900.0/w
im900 = image.resize((int(math.floor(r900*w)), int(math.floor(r900*h))), Image.ANTIALIAS)
im900.save(self.full_image_large)
r350 = 350.0/w
im350 = image.resize((int(math.floor(r350*w)), int(math.floor(r350*h))), Image.ANTIALIAS)
im350.save(self.full_image)
r120 = 120.0/w
im120 = image.resize((int(math.floor(r120*w)), int(math.floor(r120*h))), Image.ANTIALIAS)
im120.save(self.thumbnail_image)
super(Artwork, self).save()
您可以在同一个 Image
实例上执行所有三个 resize
操作 - 在本例中为 image
。只需在每个尺寸的新对象中保存该操作的结果,然后保存 that 对象而不是保存原始 image
对象。
但是,Python 的主要原则之一是 DRY——不要重复自己。上面的代码可以这样重构:
def save(self):
image = Image.open(self.full_image_large)
(w, h) = image.size
for width, target in zip([900.0, 350.0, 120.0],
[self.full_image_large,
self.full_image,
self.thumbnail_image]):
r = width/w
im = image.resize((int(math.floor(r*w)),
int(math.floor(r*h))),
Image.ANTIALIAS)
im.save(target)
super(Artwork, self).save()
zip
创建每个宽度和目标的元组。
我无法将两个想法放在一起,调整 models.ImageField
中的图像大小(如果我不尝试同时上传到我的 Amazon S3 存储桶,效果很好)并将图像上传到我的 Amazon S3桶)。
我的模特:
from django.db import models
from django.conf import settings
from storages.backends.s3boto import S3BotoStorage
from django.core.files.storage import default_storage as storage
import datetime
from PIL import Image
import math
class Artwork(models.Model):
title = models.CharField(max_length=200)
# other fields...
full_image_large = models.ImageField(storage=S3BotoStorage(location='img'))
full_image = models.ImageField(storage=S3BotoStorage(location='img'), editable=False)
thumbnail_image = models.ImageField(storage=S3BotoStorage(location='img'), editable=False)
def __str__(self):
return self.title
def save(self):
super(Artwork, self).save()
image = Image.open(self.full_image_large, 'r')
(w, h) = image.size
for width, target in zip([900.0, 350.0, 120.0],
[self.full_image_large,
self.full_image,
self.thumbnail_image]):
r = width/w
im = image.resize((int(math.floor(r*w)),
int(math.floor(r*h))),
Image.ANTIALIAS)
im.save(target, format='JPEG')
所以 full_image_large
是可编辑的,用户可以上传。我想要将这张照片调整为 900px 的宽度,无论其大小如何(保持纵横比)。然后,我还尝试将同一张照片的大小调整为 full_image
,宽度应为 350px。最后,我试图将同一张照片的大小调整为 thumbnail_image
,宽度应为 120px。
当我转到站点的管理员 url 并保存对象时,出现以下错误。
The 'full_image' attribute has no file associated with it.
第一张图片上传到 Amazon S3(如果我注释掉对其他两张图片的引用)就好了,但没有调整大小。如果有人能以最简单的方式帮助我完成我正在做的事情,那将不胜感激。谢谢。注意:我正在使用 Python3。
我也尝试过使用 django-imagekit
但没有成功。
请尝试使用以下内容:
def save(self):
image = Image.open(self.full_image_large)
(w, h) = image.size
r900 = 900.0/w
im900 = image.resize((int(math.floor(r900*w)), int(math.floor(r900*h))), Image.ANTIALIAS)
im900.save(self.full_image_large)
r350 = 350.0/w
im350 = image.resize((int(math.floor(r350*w)), int(math.floor(r350*h))), Image.ANTIALIAS)
im350.save(self.full_image)
r120 = 120.0/w
im120 = image.resize((int(math.floor(r120*w)), int(math.floor(r120*h))), Image.ANTIALIAS)
im120.save(self.thumbnail_image)
super(Artwork, self).save()
您可以在同一个 Image
实例上执行所有三个 resize
操作 - 在本例中为 image
。只需在每个尺寸的新对象中保存该操作的结果,然后保存 that 对象而不是保存原始 image
对象。
但是,Python 的主要原则之一是 DRY——不要重复自己。上面的代码可以这样重构:
def save(self):
image = Image.open(self.full_image_large)
(w, h) = image.size
for width, target in zip([900.0, 350.0, 120.0],
[self.full_image_large,
self.full_image,
self.thumbnail_image]):
r = width/w
im = image.resize((int(math.floor(r*w)),
int(math.floor(r*h))),
Image.ANTIALIAS)
im.save(target)
super(Artwork, self).save()
zip
创建每个宽度和目标的元组。