缩略图的Django模型如下:
class Thumb(models.Model):
thumb = models.ImageField(upload_to='uploads/thumb/', null=True, default=None)
视图使用pillow
包生成一个缩略图,并应使用如下代码将其保存在Thumb
实例中:
image.thumbnail((50, 50))
inst.thumb.save('thumb.jpg', ???)
为???
上的inst.thumb.save
制作image
数据的正确方法是什么
我能够让下面的代码正常工作:
thumb_temp = NamedTemporaryFile()
image.save(thumb_temp, 'JPEG', quality=80)
thumb_temp.flush()
inst.thumb.save('thumb.jpg', File(thumb_temp))
thumb_temp.close() # Probably required to ensure temp file delete at close
但是,仅仅为了将内部数据传递给inst.thumb.save
而编写临时文件似乎相当笨拙,所以我想知道是否有更好的方法来做到这一点。Django class NamedTemporaryFile
的文档。
发布于 2017-08-28 01:43:27
下面是一个可用的示例(Python3,django 1.11),它从Model.ImageField
中获取图像,使用PIL (枕头)对其执行调整大小操作,然后将结果文件保存到相同的ImageField中。希望这应该很容易适应你必须对模型图像进行的任何处理。
from io import BytesIO
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.core.files.base import ContentFile
from PIL import Image
IMAGE_WIDTH = 100
IMAGE_HEIGHT = 100
def resize_image(image_field, width=IMAGE_WIDTH, height=IMAGE_HEIGHT, name=None):
"""
Resizes an image from a Model.ImageField and returns a new image as a ContentFile
"""
img = Image.open(image_field)
if img.size[0] > width or img.size[1] > height:
new_img = img.resize((width, height))
buffer = BytesIO()
new_img.save(fp=buffer, format='JPEG')
return ContentFile(buffer.getvalue())
#assuming your Model instance is called `instance`
image_field = instance.image_field
img_name = 'my_image.jpg'
img_path = settings.MEDIA_ROOT + img_name
pillow_image = resize_image(
image_field,
width=IMAGE_WIDTH,
height=IMAGE_HEIGHT,
name=img_path)
image_field.save(img_name, InMemoryUploadedFile(
pillow_image, # file
None, # field_name
img_name, # file name
'image/jpeg', # content_type
pillow_image.tell, # size
None) # content_type_extra
)
发布于 2018-10-23 03:41:49
您可以为您的型号创建pre_save receiver:
from io import BytesIO
from functools import partial
from django.db import models
from django.core.files.uploadedfile import InMemoryUploadedFile
from PIL import Image
class Article(models.Model):
title = models.CharField(max_length=120)
slug = models.SlugField(max_length=120, unique=True)
image = models.ImageField(
upload_to=upload_image_location
)
thumbnail_image = models.ImageField(
upload_to=partial(upload_image_location, thumbnail=True),
editable=False, blank=True
)
def create_thumbnail(self):
image = Image.open(self.image.file.file)
image.thumbnail(size=(310, 230))
image_file = BytesIO()
image.save(image_file, image.format)
self.thumbnail_image.save(
self.image.name,
InMemoryUploadedFile(
image_file,
None, '',
self.image.file.content_type,
image.size,
self.image.file.charset,
),
save=False
)
@receiver(models.signals.pre_save, sender=Article)
def prepare_images(sender, instance, **kwargs):
if instance.pk:
try:
article = Article.objects.get(pk=instance.pk)
old_image = article.image
old_thumbnail_image = article.thumbnail_image
except Article.DoesNotExist:
return
else:
new_image_extension = os.path.splitext(instance.image.name)[1]
if old_image and not old_image.name.endswith(new_image_extension):
old_image.delete(save=False)
old_thumbnail_image.delete(save=False)
if not instance.thumbnail_image or not instance.image._committed:
instance.create_thumbnail()
图像缩略图是使用Pillow在create_thumbnail
方法中创建的。这种方法可以很好地与django-storages一起使用,并将缩略图保存在自定义存储中,名称类似于“文章_slug_thumbnail.jpeg”。
我的upload_image_location方法:
def upload_image_location(instance, filename, thumbnail=False):
_, ext = os.path.splitext(filename)
return f'articles/{instance.slug}{f"_thumbnail" if thumbnail else ""}{ext}'
发布于 2021-05-19 17:52:30
class Profile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
image = models.ImageField(default = 'default.jpg',upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
def save(self):
super().save()
img = Image.open(self.image.path)
if img.height >300 or img.width >300:
oputput_size = (300,300)
img.thumbnail(oputput_size)
img.save(self.image.path)
https://stackoverflow.com/questions/32945292
复制相似问题