I am trying to implement a Django ImageField class function for resizing images however I am not certain where this function accepts my new image dimensions
Running on Linux and Python 3.7
I've had a look at this documentation, but can't quite make sense of it: https://docs.djangoproject.com/en/1.11/_modules/django/db/models/fields/files/#ImageField
I'd really appreciate it if someone can show me an example of how to use this function.
EDIT
I haven't successfully managed to resize my image dimensions yet, which is what i am trying to achieve. How may I resize this image before I save it given it is being fetched by ImageField
(I found the update_dimensions_fields
class function for ImageField
however i cant figure out how to use it)
class Posts(models.Model):
title = models.CharField(max_length=200, blank=True)
body = models.TextField(blank=True)
created_at = models.DateTimeField(default=datetime.datetime.now)
post_image = models.ImageField(upload_to=get_image_path, blank=True, null=True)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
# I would like to use the function beneath to resize my images before I save them to my database
self.post_image.update_dimension_fields(self, instance, force=False, *args, **kwargs)
super().save(*args, **kwargs) # Call the "real" save() method.
class Meta:
verbose_name_plural = "Posts"
You could use the django-resized library. It resizes images when uploaded and stores them for you.
from django_resized import ResizedImageField
class Posts(models.Model):
title = models.CharField(max_length=200, blank=True)
body = models.TextField(blank=True)
created_at = models.DateTimeField(default=datetime.datetime.now)
post_image = ResizedImageField(size=[500, 300], upload_to=get_image_path, blank=True, null=True)
def __str__(self):
return self.title
**
This will work **First of all install "PIL Fork" using 'pip install pillow
from PIL import Image
def __str__(self):
return self.title
def save(self, *args, **kwargs):
super(Posts, self).save(*args, **kwargs)
imag = Image.open(self.post_image.path)
if imag.width > 400 or imag.height> 300:
output_size = (400, 300)
imag.thumbnail(output_size)
imag.save(self.post_image.path)
class Meta:
verbose_name_plural = "Posts"
You can use this method to resize the image before saving it: (you need pip install pillow
)
import os
from io import BytesIO
from PIL import Image as PilImage
from django.core.files.base import ContentFile
from django.core.files.uploadedfile import InMemoryUploadedFile, TemporaryUploadedFile
def resize_uploaded_image(image, max_width, max_height):
size = (max_width, max_height)
# Uploaded file is in memory
if isinstance(image, InMemoryUploadedFile):
memory_image = BytesIO(image.read())
pil_image = PilImage.open(memory_image)
img_format = os.path.splitext(image.name)[1][1:].upper()
img_format = 'JPEG' if img_format == 'JPG' else img_format
if pil_image.width > max_width or pil_image.height > max_height:
pil_image.thumbnail(size)
new_image = BytesIO()
pil_image.save(new_image, format=img_format)
new_image = ContentFile(new_image.getvalue())
return InMemoryUploadedFile(new_image, None, image.name, image.content_type, None, None)
# Uploaded file is in disk
elif isinstance(image, TemporaryUploadedFile):
path = image.temporary_file_path()
pil_image = PilImage.open(path)
if pil_image.width > max_width or pil_image.height > max_height:
pil_image.thumbnail(size)
pil_image.save(path)
image.size = os.stat(path).st_size
return image
Then use it in the clean method of the image field in your form:
class ImageForm(forms.Form):
IMAGE_WIDTH = 450
IMAGE_HEIGHT = 450
image = forms.ImageField()
def clean_image(self):
image = self.cleaned_data.get('image')
image = resize_uploaded_image(image, self.IMAGE_WIDTH, self.IMAGE_HEIGHT)
return image
To understand how the resize_uploaded_image
method works, you may read about how Django handles uploaded files in the docs, here and here .
You can use the django-imagekit library.
Pillow
. (If you're using an ImageField
in Django, you should have already done this.) pip install django-imagekit
'imagekit'
to your INSTALLED_APPS
list in your project's settings.py
from django.db import models
from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFill
class Profile(models.Model):
avatar = models.ImageField(upload_to='avatars')
avatar_thumbnail = ImageSpecField(source='avatar',
processors=[ResizeToFill(100, 50)],
format='JPEG',
options={'quality': 60})
Pay attention to the source
attribute of ImageSpecField
which directs to the actual image field ( avatar
in this case) as ImageSpecField are virtual in nature, you can read more about it here
<img src="{{ profile.avatar_thumbnail.url }}" />
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.