This is my forms.py:
class UploadImageForm(forms.ModelForm): class Meta: model = UserImages fields = ['photo']
and this is my models.py:
class UserImages(models.Model): user = models.ForeignKey(User) photo = models.ImageField(upload_to=get_file_path)
and this is my view:
def uploadImageView(request): if request.method == 'POST': form = UploadImageForm(request.POST, request.FILES) if form.is_valid(): instance = form.save(commit=False) instance.user = request.user instance.save() return redirect('/') else: form = UploadImageForm() return render(request, 'uploadImagePage.html', {'uploadImageForm': form})
But this only saves the image being uploaded. How do I save a thumbnail version of the image as well with the thumbnail version of the image having the exact same name except with the word 'thumbail' after it?
The tutorials I read said I can do
im = Image.open(infile) im.thumbnail(size, Image.ANTIALIAS)
to get a thumbnail but in my situation, the image isn't even saved yet.
Based on xjtian's answer. This works for Python 3:
import os.path from PIL import Image from io import BytesIO from django.core.files.base import ContentFile from .my_app_settings import THUMB_SIZE class Photo(models.Model): photo = models.ImageField(upload_to='photos') thumbnail = models.ImageField(upload_to='thumbs', editable=False) def save(self, *args, **kwargs): if not self.make_thumbnail(): # set to a default thumbnail raise Exception('Could not create thumbnail - is the file type valid?') super(Photo, self).save(*args, **kwargs) def make_thumbnail(self): image = Image.open(self.photo) image.thumbnail(THUMB_SIZE, Image.ANTIALIAS) thumb_name, thumb_extension = os.path.splitext(self.photo.name) thumb_extension = thumb_extension.lower() thumb_filename = thumb_name + '_thumb' + thumb_extension if thumb_extension in ['.jpg', '.jpeg']: FTYPE = 'JPEG' elif thumb_extension == '.gif': FTYPE = 'GIF' elif thumb_extension == '.png': FTYPE = 'PNG' else: return False # Unrecognized file type # Save thumbnail to in-memory file as StringIO temp_thumb = BytesIO() image.save(temp_thumb, FTYPE) temp_thumb.seek(0) # set save=False, otherwise it will run in an infinite loop self.thumbnail.save(thumb_filename, ContentFile(temp_thumb.read()), save=False) temp_thumb.close() return True
To do this, you should add a new ImageField
to your current UserImages
model to hold the thumbnail, then override your the save
method to create and save the thumbnail after the full image is saved.
I've adapted the following snippet of code from one of my projects that did exactly this, I'm pretty sure this will do exactly what you need it to do:
from cStringIO import StringIO import os from django.db import models from django.core.files.base import ContentFile from django.core.files.storage import default_storage as storage from PIL import Image # Thumbnail size tuple defined in an app-specific settings module - e.g. (400, 400) from app.settings import THUMB_SIZE class Photo(models.Model): """ Photo model with automatically generated thumbnail. """ photo = models.ImageField(upload_to='photos') thumbnail = models.ImageField(upload_to='thumbs', editable=False) def save(self, *args, **kwargs): """ Make and save the thumbnail for the photo here. """ super(Photo, self).save(*args, **kwargs) if not self.make_thumbnail(): raise Exception('Could not create thumbnail - is the file type valid?') def make_thumbnail(self): """ Create and save the thumbnail for the photo (simple resize with PIL). """ fh = storage.open(self.photo.name, 'r') try: image = Image.open(fh) except: return False image.thumbnail(THUMB_SIZE, Image.ANTIALIAS) fh.close() # Path to save to, name, and extension thumb_name, thumb_extension = os.path.splitext(self.photo.name) thumb_extension = thumb_extension.lower() thumb_filename = thumb_name + '_thumb' + thumb_extension if thumb_extension in ['.jpg', '.jpeg']: FTYPE = 'JPEG' elif thumb_extension == '.gif': FTYPE = 'GIF' elif thumb_extension == '.png': FTYPE = 'PNG' else: return False # Unrecognized file type # Save thumbnail to in-memory file as StringIO temp_thumb = StringIO() image.save(temp_thumb, FTYPE) temp_thumb.seek(0) # Load a ContentFile into the thumbnail field so it gets saved self.thumbnail.save(thumb_filename, ContentFile(temp_thumb.read()), save=True) temp_thumb.close() return True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With