Загрузка и изменение размера изображения в Django
3 Mad Rapper X [2011-08-11 07:06:00]
У меня есть стандартная форма Django с полем изображения. Когда изображение загружается, я хотел бы убедиться, что изображение не превышает 300 пикселей на 300 пикселей. Вот мой код:
def post(request):
if request.method == 'POST':
instance = Product(posted_by=request.user)
form = ProductModelForm(request.POST or None, request.FILES or None)
if form.is_valid():
new_product = form.save(commit=False)
if 'image' in request.FILES:
img = Image.open(form.cleaned_data['image'])
img.thumbnail((300, 300), Image.ANTIALIAS)
# this doesnt save the contents here...
img.save(new_product.image)
# ..because this prints the original width (2830px in my case)
print new_product.image.width
Проблема, с которой я столкнулась, - это не ясно, как я получаю тип Image
, преобразованный в тип типа ImageField.
python django image-uploading python-imaging-library
6 ответов
3 Martey [2011-08-11 09:59:00]
Из документации по ImageField сохранить метод:
Обратите внимание, что аргумент content должен быть экземпляром django.core.files.File, а не встроенным файловым объектом Python.
Это означает, что вам нужно преобразовать PIL.Image
(img
) в объект файла Python, а затем преобразовать объект Python в объект django.core.files.File
. Что-то вроде этого (я не тестировал этот код) может работать:
img.thumbnail((300, 300), Image.ANTIALIAS)
# Convert PIL.Image to a string, and then to a Django file
# object. We use ContentFile instead of File because the
# former can operate on strings.
from django.core.files.base import ContentFile
djangofile = ContentFile(img.tostring())
new_product.image.save(filename, djangofile)
1 Alexey Kuleshevich [2014-12-24 07:35:00]
Вот приложение, которое может позаботиться об этом: django-smartfields
from django.db import models
from smartfields import fields
from smartfields.dependencies import FileDependency
from smartfields.processors import ImageProcessor
class Product(models.Model):
image = fields.ImageField(dependencies=[
FileDependency(processor=ImageProcessor(
scale={'max_width': 300, 'max_height': 300}))
])
1 James Lin [2012-11-22 21:04:00]
Там вы идете, просто измените немного, чтобы удовлетворить ваши потребности:
class PhotoField(forms.FileField, object):
def __init__(self, *args, **kwargs):
super(PhotoField, self).__init__(*args, **kwargs)
self.help_text = "Images over 500kb will be resized to keep under 500kb limit, which may result in some loss of quality"
def validate(self,image):
if not str(image).split('.')[-1].lower() in ["jpg","jpeg","png","gif"]:
raise ValidationError("File format not supported, please try again and upload a JPG/PNG/GIF file")
def to_python(self, image):
try:
limit = 500000
num_of_tries = 10
img = Image.open(image.file)
width, height = img.size
ratio = float(width) / float(height)
upload_dir = settings.FILE_UPLOAD_TEMP_DIR if settings.FILE_UPLOAD_TEMP_DIR else '/tmp'
tmp_file = open(os.path.join(upload_dir, str(uuid.uuid1())), "w")
tmp_file.write(image.file.read())
tmp_file.close()
while os.path.getsize(tmp_file.name) > limit:
num_of_tries -= 1
width = 900 if num_of_tries == 0 else width - 100
height = int(width / ratio)
img.thumbnail((width, height), Image.ANTIALIAS)
img.save(tmp_file.name, img.format)
image.file = open(tmp_file.name)
if num_of_tries == 0:
break
except:
pass
return image
Источник: http://james.lin.net.nz/2012/11/19/django-snippet-reduce-image-size-during-upload/
1 dusual [2011-08-11 09:55:00]
Как использовать стандартное поле изображения https://github.com/humanfromearth/django-stdimage
0 Gagaro [2017-06-27 16:31:00]
Вы можете использовать мою библиотеку django-sizedimagefield для этого, она не имеет дополнительной зависимости и очень проста в использовании.
0 John Pang [2014-08-09 22:29:00]
Попробуйте мое решение здесь: qaru.site/questions/399762/...
Выделение
- Использование подушки для обработки изображений (требуется два пакета: libjpeg-dev, zlib1g-dev)
- Использование модели и ImageField в качестве хранилища
- Использование HTTP POST или PUT с multipart/form
- Не нужно вручную сохранять файл на диск.
- Создайте несколько разрешений и сохраните их размеры.