我无法将两个想法放在一起,从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
,宽度应为350像素。最后,我正在尝试将同一张照片的大小调整为thumbnail_image
,宽度应为120像素。
当我访问我网站的管理员网址并保存对象时,我收到以下错误消息。
The 'full_image' attribute has no file associated with it.
第一张图片上传到Amazon S3(如果我注释掉对其他两张图片的引用)就好了,但没有任何内容可以调整大小。如果有人能用最简单的方法帮助我完成我正在做的事情,那将不胜感激。谢谢。注意:我使用的是Python3。
我也试过使用django-imagekit
但没有成功。
答案 0 :(得分:1)
请尝试使用以下内容:
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()
在这种情况下,您可以在同一resize
个实例 - Image
上执行所有三项image
操作。只需将该操作的结果保存在每个大小的新对象中,然后保存该对象,而不是保存原始image
对象。
然而,Python的主要原则之一就是DRY - Don不要重复自己。上面的代码可以像这样重构:
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
创建每个宽度和目标的元组。