python - 在 Django 中上传时调整两个图像的大小

标签 python django upload resize

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

模型.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 不起作用。

最佳答案

这是我使用的一个实用函数,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)

关于python - 在 Django 中上传时调整两个图像的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24855460/

相关文章:

python - 使用 python OpenCV 从 Kinect 设备检索 channel

python - 在 raw_input 中输入 float 、整数或方程来定义变量

json - 将有效负载预处理到 Django 中的惯用方法是什么?

node.js - req.form 不是实例化的多方表单对象

javascript - 客户端上传前文件压缩

python - 如何在 numpy.ndarray 上获得 rolling(window = 3).max()?

python:如果它只有常量,那么实例化一个类与引用相比有什么缺点吗?

Django,mongodb,Tastypie-nonrel : List of ForeignKey

python - 线程启动时出现未处理的异常

php - 调用未定义函数 exif_imagetype()