Как сохранить обработанное изображение подушки в уже существующем объекте Django
Я создал объектную модель, как показано ниже
from django.db import models
# Create your models here.
class ImageModel(models.Model):
image = models.ImageField(upload_to='images/')
editedImg = models.ImageField(upload_to='images/')
def delete(self, *args, **kwargs):
self.image.delete()
self.editedImg.delete()
super().delete(*args, **kwargs)
А вот что я пытаюсь сделать в функции
from django.shortcuts import render
from EditorApp.forms import ImageForm
from EditorApp.models import ImageModel
from django.http import HttpResponseRedirect
from PIL import Image
def edit_column(request):
codArr = request.POST.getlist('codArr[]')
imgs = ImageModel.objects.first()
orgImage = ImageModel.objects.first().image
orgImage = Image.open(orgImage)
croppedImg = orgImage.crop((int(codArr[0]), int(codArr[1]), int(codArr[2]), int(codArr[3])))
# croppedImg.show()
# imgs.editedImg = croppedImg
# imgs.save()
return HttpResponseRedirect("/editing/")
Что я пытаюсь сделать, это то, что codArr состоит из координат top(x, y) и bottom(x, y) в форме массива (Что не является проблемой и проверяется (croppedImg.show()
показал желаемое обрезанное изображение) и обрабатывается и используется для обрезки изображения). Обрезка изображения работает нормально. Но я пытаюсь сохранить обрезанное изображение в editedImg
модели, используемой выше. То, что я пытался сделать, прокомментировано выше, но выдает ошибку AttributeError: _committed
Поскольку я не использовал никакого имени для изображения в модели, так как оно не требуется. Помогите пожалуйста, буду очень благодарен.
вы должны сделать это следующим образом:
from io import BytesIO
from api.models import ProductPicture
from django.core import files
codArr = request.POST.getlist('codArr[]')
img_obj = ImageModel.objects.first()
orgImage = img_obj.image
orgImage = Image.open(orgImage)
croppedImg = orgImage.crop((int(codArr[0]), int(codArr[1]), int(codArr[2]), int(codArr[3])))
thumb_io = BytesIO() # create a BytesIO object
croppedImg.save(thumb_io, 'png')
editedImg = files.File(thumb_io, name=file_name)
img_obj.editedImg = editedImg
img_obj.save()
Вы можете использовать контекстный менеджер Python для открытия изображения и сохранения его в нужном хранилище, в этом случае я использую images
dir.
Pillow обрезает изображение, а image.save() сохраняет его в файловой системе, после чего его можно добавить в ImageField Django и сохранить в DB.
Менеджер контекста заботится об открытии и закрытии файлов, Pillow заботится об изображении, а Django заботится о БД.
from PIL import Image
with Image.open(orgImage) as image:
file_name = image.filename # Can be replaced by orgImage filename
cropped_path = f"images/croped-{file_name}"
# The crop method from the Image module takes four coordinates as input.
# The right can also be represented as (left+width)
# and lower can be represented as (upper+height).
(left, upper, right, lower) = (20, 20, 100, 100)
# Here the image "image" is cropped and assigned to new variable im_crop
im_crop = image.crop((left, upper, right, lower))
im_crop.save(cropped_path)
imgs.editedImg = cropped_path
imgs.save()
@misraX я сделал так, как вы показали
def edit_column(request):
codArr = request.POST.getlist('codArr[]')
imgs = ImageModel.objects.first()
orgImage = ImageModel.objects.first().image
path_to_save = str(Path(__file__).resolve().parent.parent)
with Image.open(orgImage) as image:
print(Path(__file__).resolve().parent.parent)
cropped_path = path_to_save + "/media/images/croped.png"
print(cropped_path)
im_crop = image.crop((int(codArr[0]), int(codArr[1]), int(codArr[2]), int(codArr[3])))
im_crop.save(cropped_path)
imgs.editedImg = cropped_path
imgs.save()
В админке сайта django. Текущая ссылка на изображение отличается. Ссылка на сайт django
для уже сохраненного изображения в настоящее время ссылка images/tree.jpg
А для нового обновленного обрезанного изображения в настоящее время ссылка такова: /home/aashiq/Documents/Django/My_Django_Stuff/MyProject/ImageEditor/media/images/croped.png
Пожалуйста, помогите! И спасибо всем за предыдущий ответ.