将 PIL.Image 转换为 wagtailimages.Image
Converting a PIL.Image to wagtailimages.Image
我正在使用 Pillow 创建图像的缩略图,但是我无法将它们存储在字段中 image_thumbnail 因为该字段的类型是图像,我收到一个异常:ValueError:无法分配“ ": "GalleryItem.image_thumbnail" 必须是 "Image" 实例。
Wagtail 已经在使用 Pillow,但我找不到简单的方法...
class GalleryItem(models.Model):
image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
help_text='Image size must be 1440 x 961 px.'
)
image_thumbnail = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
)
category = models.ForeignKey(
'ImageCategorie',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+'
)
def createThumbnails(self):
size = (300, 300)
outfile = self.image.title.split('.')[0] + ".thumbnail.jpg"
try:
im = Image.open(self.image.file)
im.thumbnail(size)
im.save(outfile, format="jpeg")
return im
except IOError:
print("cannot create thumbnail for", self.image.file)
def save(self, *args, **kwargs):
self.image_thumbnail = self.createThumbnails()
import ipdb; ipdb.set_trace()
super(GalleryItem, self).save(*args, **kwargs)
def __str__(self):
return self.image.title
从概念上讲,PIL.Image 和 wagtailimages.Image 是两个不同的东西:PIL.Image 代表一个图像文件(即一组特定的像素),而 wagtailimages.Image 是一个数据库将 "a picture" 记录为一段可选择且可重复使用的编辑内容,并带有支持元数据(通常只是标题,但 other fields are possible too) and the ability to re-render it at any size. Using wagtailimages.Image to store a thumbnailed version of an existing image is overkill, and you're probably better off making the image_thumbnail
field a Django ImageField
(以 "bunch of pixels" 的方式存储图像)。
如果您真的想在这里使用 wagtailimages.Image,可以,但是您需要为图像创建数据库记录,然后然后将其附加到您的图库项目 object。代码将类似于:
from io import BytesIO
from PIL import Image as PILImage
from django.core.files.images import ImageFile
from wagtail.images.models import Image as WagtailImage
...
pil_image = PILImage.open(self.image.file)
pil_image.thumbnail(size)
f = BytesIO()
pil_image.save(f, 'JPEG')
wagtail_image = WagtailImage.objects.create(
title=('thumbnail of %s' % self.image.title),
file=ImageFile(f, name=outfile)
)
self.image_thumbnail = wagtail_image
在看到 gasman 的回答之前,我使用以下代码成功了:
def createThumbnails(self):
# Set our max thumbnail size in a tuple (max width, max height)
THUMBNAIL_SIZE = (200, 200)
outfile = self.image.title.split('.')[0] + ".thumbnail.jpg"
extention = self.image.filename.split('.')[1]
img_io = BytesIO()
PIL_TYPE = 'jpeg'
try:
# Open original photo which we want to thumbnail using PIL's Image
im = PILImage.open(BytesIO(self.image.file.read()))
im.thumbnail(THUMBNAIL_SIZE, PILImage.ANTIALIAS)
im.save(img_io, PIL_TYPE)
img_io.seek(0)
# Save image to a SimpleUploadedFile which can be saved into
# ImageField
suf = SimpleUploadedFile(outfile, img_io.read())
self.screenshot.save(outfile, suf, save=False)
except IOError:
print("cannot create thumbnail for", self.image.file)
def save(self, *args, **kwargs):
self.createThumbnails()
super(GalleryItem, self).save(force_update=False)
我正在使用 Pillow 创建图像的缩略图,但是我无法将它们存储在字段中 image_thumbnail 因为该字段的类型是图像,我收到一个异常:ValueError:无法分配“ ": "GalleryItem.image_thumbnail" 必须是 "Image" 实例。
Wagtail 已经在使用 Pillow,但我找不到简单的方法...
class GalleryItem(models.Model):
image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
help_text='Image size must be 1440 x 961 px.'
)
image_thumbnail = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
)
category = models.ForeignKey(
'ImageCategorie',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+'
)
def createThumbnails(self):
size = (300, 300)
outfile = self.image.title.split('.')[0] + ".thumbnail.jpg"
try:
im = Image.open(self.image.file)
im.thumbnail(size)
im.save(outfile, format="jpeg")
return im
except IOError:
print("cannot create thumbnail for", self.image.file)
def save(self, *args, **kwargs):
self.image_thumbnail = self.createThumbnails()
import ipdb; ipdb.set_trace()
super(GalleryItem, self).save(*args, **kwargs)
def __str__(self):
return self.image.title
从概念上讲,PIL.Image 和 wagtailimages.Image 是两个不同的东西:PIL.Image 代表一个图像文件(即一组特定的像素),而 wagtailimages.Image 是一个数据库将 "a picture" 记录为一段可选择且可重复使用的编辑内容,并带有支持元数据(通常只是标题,但 other fields are possible too) and the ability to re-render it at any size. Using wagtailimages.Image to store a thumbnailed version of an existing image is overkill, and you're probably better off making the image_thumbnail
field a Django ImageField
(以 "bunch of pixels" 的方式存储图像)。
如果您真的想在这里使用 wagtailimages.Image,可以,但是您需要为图像创建数据库记录,然后然后将其附加到您的图库项目 object。代码将类似于:
from io import BytesIO
from PIL import Image as PILImage
from django.core.files.images import ImageFile
from wagtail.images.models import Image as WagtailImage
...
pil_image = PILImage.open(self.image.file)
pil_image.thumbnail(size)
f = BytesIO()
pil_image.save(f, 'JPEG')
wagtail_image = WagtailImage.objects.create(
title=('thumbnail of %s' % self.image.title),
file=ImageFile(f, name=outfile)
)
self.image_thumbnail = wagtail_image
在看到 gasman 的回答之前,我使用以下代码成功了:
def createThumbnails(self):
# Set our max thumbnail size in a tuple (max width, max height)
THUMBNAIL_SIZE = (200, 200)
outfile = self.image.title.split('.')[0] + ".thumbnail.jpg"
extention = self.image.filename.split('.')[1]
img_io = BytesIO()
PIL_TYPE = 'jpeg'
try:
# Open original photo which we want to thumbnail using PIL's Image
im = PILImage.open(BytesIO(self.image.file.read()))
im.thumbnail(THUMBNAIL_SIZE, PILImage.ANTIALIAS)
im.save(img_io, PIL_TYPE)
img_io.seek(0)
# Save image to a SimpleUploadedFile which can be saved into
# ImageField
suf = SimpleUploadedFile(outfile, img_io.read())
self.screenshot.save(outfile, suf, save=False)
except IOError:
print("cannot create thumbnail for", self.image.file)
def save(self, *args, **kwargs):
self.createThumbnails()
super(GalleryItem, self).save(force_update=False)