【问题标题】:Django 1.11: Flip image horizontally before saving into a Django modelDjango 1.11:在保存到 Django 模型之前水平翻转图像
【发布时间】:2017-10-18 20:10:28
【问题描述】:

我正在做这个应用程序,我在其中获取用户的图像,然后使用来自Pillow 库的ImageOps 水平翻转它。为此,我制作了一个像上面这样的模型:

from django.db import models


class ImageClient(models.Model):
    image = models.ImageField(null=False, blank=False)

我使用ImageField 制作了一个表单,并使用enctype="multipart/form-data" 制作了一个html 表单,在我看来,我做了以下事情:

from django.shortcuts import render, redirect
from .forms import ImageForm
from .models import ImageClient
from PIL import Image, ImageOps

def new(request):
    """
    Returns mirror image from client.
    """
    if request.method == 'POST':
        form = ImageForm(request.POST, request.FILES)
        if form.is_valid():
            image = Image.open(form.cleaned_data['image'])
            image = ImageOps.mirror(image)
            form_image = ImageClient(image=image)
            form_image.save()
            return redirect('img:detail', pk=form_image.id)
    else:
        form = ImageForm()
    return render(request, 'img/new_egami.html', {'form':form})
....

如您所见,当检查表单是否有效时,我打开表单的图像并将其水平翻转(使用ImageOps.mirror())然后保存。但我总是收到此错误'Image' object has no attribute '_committed'。我知道 Image object 来自 Pillow,但我不明白这个错误。有人可以解释和/或解决这个错误吗?

【问题讨论】:

  • ImageField 必须有一个upload_to 属性:image = models.ImageField(upload_to='folder-to-upload-photos/', null=False, blank=False)

标签: django


【解决方案1】:

因为图像是PIL Image 对象而引发错误,而 Django 期望并需要它自己的File 对象。您可以将 Image 对象保存到绝对文件路径,然后引用它,但有更有效的方法 herehere。这是对@madzohan 在后一个链接中为您的图像操作所做的回答的改编:

# models.py

from io import BytesIO
from django.core.files.base import ContentFile
from PIL import Image, ImageOps

class ImageClient(models.Model):
    image = models.ImageField(null=False, blank=False, upload_to="image/path/")

    def save(self, *args, **kwargs):
        pil_image_obj = Image.open(self.image)
        new_image = ImageOps.mirror(pil_image_obj)

        new_image_io = BytesIO()
        new_image.save(new_image_io, format='JPEG')

        temp_name = self.image.name
        self.image.delete(save=False)  

        self.image.save(
            temp_name,
            content=ContentFile(new_image_io.getvalue()),
            save=False
        )

        super(ImageClient, self).save(*args, **kwargs)

和views.py:

...
if form.is_valid():
    new_image = form.save()
    return redirect('img:detail', pk=new_image.id)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多