在Django中上传两个图像大小

时间:2014-07-20 22:20:23

标签: python django upload resize

我想制作一张有两张图片的表格,第一张是原始照片的大小调整,第二张是缩略图,我想将图片保存在两个不同的目录中,这就是我正在做的但是我无法保存缩略图。

models.py

class Cakes(models.Model):
    title = models.CharField(max_length=100, unique=True)
    descrip = models.TextField(verbose_name='Descripction')
    imagen = models.ImageField(upload_to='Cake', verbose_name='Imagen')
    imagen2 = models.ImageField(upload_to='Cake/thumbnail', verbose_name='Imagen2')
    time_regist = models.DateField(auto_now=True)

    def __unicode__(self):
        return self.titulo

view.py

def new_cake(request):
    if request.method == 'POST':
        formulario = CakesForm(request.POST, request.FILES)
        if formulario.is_valid():
            resize_imagen(request.FILES['imagen'],250)

            resize_imagen(request.FILES['imagen'],960)

            formulario.save()
            return HttpResponseRedirect('/paneladmin')
    else:
        formulario = CakesForm()
    return render_to_response('nuevocake.html', {'formulario': formulario}, context_instance = RequestContext(request))

def resize_imagen(img, size):
    import StringIO, os
    from PIL import Image, ImageOps
    from django.core.files import File
    imagenarchivo = StringIO.StringIO(img.read())
    imagenImagen = Image.open(imagenarchivo)
    if size == 250:
        imagenImagen.thumbnail((250,120), Image.ANTIALIAS)
    else:
        imagenImagen.thumbnail((960,720), Image.ANTIALIAS)
    # re-initialize imageFile

    imagefile = StringIO.StringIO()
    imagenImagen.save(imagefile,'JPEG')

我不想要原始图像,因为原始文件很重,这就是为什么我要尝试调整大小。函数resize_imagen不起作用。

1 个答案:

答案 0 :(得分:1)

这是我使用的实用程序函数save_thumbnail。我建议将其放在app_name/utils.py

这具有从数据库中获取原始图像(额外查询...)的附加功能,以确认在更新缩略图图像之前图像已更改以保存在PIL处理上。

(如果您通过force_thumbnail,它将始终创建缩略图而不提取原始图片,以查看自上次保存后它是否已更改。)

# models.py
from django.db import transaction
import app_name.utils

class Node(models.Model):
    # ...
    image = models.ImageField(upload_to='node_images', null=False)
    thumbnail_200w = models.ImageField(upload_to='node_images/200w', null=False)

    def save(self, *args, **kwargs):
        with transaction.commit_on_success():
            # instance_class, self, image_attr, thumbnail_attr, width, height=None
            cms.utils.save_thumbnail(Node, self, 'image', 'thumbnail_200w', 200, None)
            super(Node, self).save(*args, **kwargs)  

# utils.py
from PIL import Image
from cStringIO import StringIO
from django.core.files.uploadedfile import SimpleUploadedFile
import os

def save_thumbnail(instance_class, instance, image_attr, thumbnail_attr, max_width, max_height=None, force_thumbnail=False):
    new_image = getattr(instance, image_attr)
    if not new_image:
        return

    if not force_thumbnail:
        if instance.id:
            existing_image = getattr(instance_class.objects.get(id=instance.id), image_attr)
        else:
            existing_image = None

        if new_image == existing_image:
            return  # exit because the file hasn't changed, no need to generate thumbs

    super(instance_class, instance).save()

    thumbnail = create_thumbnail(getattr(instance, image_attr).file, max_width, max_height)
    getattr(instance, thumbnail_attr).save(thumbnail.name, thumbnail, save=False)


def create_thumbnail(original, max_width, max_height=None):

    # Open original photo which we want to thumbnail using PIL's Image
    image = Image.open(StringIO(original.read()))

    # Set our max thumbnail size in a tuple (max width, max height)
    if max_height:
        THUMBNAIL_SIZE = (max_width, max_height)
        image.thumbnail(THUMBNAIL_SIZE, Image.ANTIALIAS)
    else:
        # scale to width, keeping aspect
        width_ratio = (max_width/float(image.size[0]))
        hsize = int((float(image.size[1]) * float(width_ratio)))
        THUMBNAIL_SIZE = (max_width, hsize)
        image = image.resize(THUMBNAIL_SIZE, Image.ANTIALIAS)

    DJANGO_TYPE = original.file.content_type

    if DJANGO_TYPE == 'image/jpeg':
     PIL_TYPE = 'jpeg'
     FILE_EXTENSION = 'jpg'
    elif DJANGO_TYPE == 'image/png':
     PIL_TYPE = 'png'
     FILE_EXTENSION = 'png'
    elif DJANGO_TYPE == 'image/gif':
     PIL_TYPE = 'gif'
     FILE_EXTENSION = 'gif'


    # Save the thumbnail
    temp_handle = StringIO()
    image.save(temp_handle, PIL_TYPE)
    temp_handle.seek(0)

    # Save image to a SimpleUploadedFile which can be saved into ImageField
    return SimpleUploadedFile(os.path.split(original.name)[-1],
         temp_handle.read(), content_type=DJANGO_TYPE)