Преобразование PIL.Image в wagtailimages.Image - PullRequest
0 голосов
/ 27 августа 2018

Я создаю миниатюру для изображений с помощью Pillow, однако я не могу сохранить их в поле image_thumbnail, поскольку поле имеет тип Image, и я получаю исключение: ValueError: Невозможно назначить "": "GalleryItem.image_thumbnail "должен быть экземпляром" Image ".

Трясогузка уже использует подушку, но я не могу найти легкий способ сделать это ...

 class GalleryItem(models.Model):
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text='Image size must be 1440 x 961 px.'
    )
    image_thumbnail = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )
    category = models.ForeignKey(
        'ImageCategorie',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )

    def createThumbnails(self):
        size = (300, 300)
        outfile = self.image.title.split('.')[0] + ".thumbnail.jpg"
        try:
            im = Image.open(self.image.file)
            im.thumbnail(size)
            im.save(outfile, format="jpeg")
            return im
        except IOError:
            print("cannot create thumbnail for", self.image.file)

    def save(self, *args, **kwargs):
        self.image_thumbnail = self.createThumbnails()
        import ipdb; ipdb.set_trace()
        super(GalleryItem, self).save(*args, **kwargs)

    def __str__(self):
        return self.image.title

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Перед тем как увидеть ответ газовика, мне удалось набрать следующий код:

def createThumbnails(self):
        # Set our max thumbnail size in a tuple (max width, max height)
        THUMBNAIL_SIZE = (200, 200)
        outfile = self.image.title.split('.')[0] + ".thumbnail.jpg"
        extention = self.image.filename.split('.')[1]
        img_io = BytesIO()
        PIL_TYPE = 'jpeg'
        try:
            # Open original photo which we want to thumbnail using PIL's Image
            im = PILImage.open(BytesIO(self.image.file.read()))
            im.thumbnail(THUMBNAIL_SIZE, PILImage.ANTIALIAS)
            im.save(img_io, PIL_TYPE)
            img_io.seek(0)
            # Save image to a SimpleUploadedFile which can be saved into
            # ImageField
            suf = SimpleUploadedFile(outfile, img_io.read())
            self.screenshot.save(outfile, suf, save=False)
        except IOError:
            print("cannot create thumbnail for", self.image.file)

    def save(self, *args, **kwargs):
        self.createThumbnails()
        super(GalleryItem, self).save(force_update=False)
0 голосов
/ 28 августа 2018

Концептуально, PIL.Image и wagtailimages.Image - это две разные вещи: PIL.Image представляет файл изображения (т. Е. Определенный набор пикселей), а wagtailimages.Image - это запись базы данных для "картинки" в виде фрагмента редактируемый контент с возможностью выбора и повторного использования, с поддержкой метаданных (обычно это просто заголовок, но возможны и другие поля ) и возможностью повторного рендеринга в любом размере. Использование wagtailimages.Image для хранения уменьшенной версии существующего изображения излишне, и вам, вероятно, лучше сделать поле image_thumbnail Django ImageField (которое хранит изображение в «связке пикселей "смысл).

Если вы действительно хотите использовать wagtailimages.Image здесь, вы можете, но вам нужно будет создать запись базы данных для изображения и , а затем присоединить ее к вашему объекту GalleryItem. Код будет что-то вроде:

from io import BytesIO

from PIL import Image as PILImage
from django.core.files.images import ImageFile
from wagtail.images.models import Image as WagtailImage

...
    pil_image = PILImage.open(self.image.file)
    pil_image.thumbnail(size)
    f = BytesIO()
    pil_image.save(f, 'JPEG')

    wagtail_image = WagtailImage.objects.create(
        title=('thumbnail of %s' % self.image.title),
        file=ImageFile(f, name=outfile)
    )
    self.image_thumbnail = wagtail_image
...