英文:
How can I resign Photo in Django Form
问题
我正在进行一个Django项目,我想要将图像大小减小到小于300KB,并将图像裁剪为1280px * 820px。目标是确保每上传的图像都是相同的,不管初始图像如何,任何最佳解决方案都将不胜感激。
下面是我尝试过的内容,但都没有起作用。
ALLOWED_EXTENSIONS = ('.gif', '.jpg', '.jpeg')
class PropertyForm(forms.ModelForm):
description = forms.CharField(label='Property Description:', max_length=60, widget=forms.TextInput(attrs={'placeholder': 'Briefly Describe your Property. E.g. Bedroom & Palour with Private Detached Bathroom'}))
state = forms.ChoiceField(choices=Property.STATE_CHOICES, required=False)
state_lga = forms.CharField(label='Local Govt. Area:', max_length=12, widget=forms.TextInput(attrs={'placeholder': 'Enter Local Govt. of Property.'}))
address = forms.CharField(label='Property Address:', max_length=60, widget=forms.TextInput(attrs={'placeholder': 'Enter Street Name with Number and Town Name only.'}))
class Meta:
model = Property
fields = ('description', 'address', 'country', 'state', 'state_lga', 'property_type', 'bedrooms', 'bathroom_type', 'price', 'is_available', 'image')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['bedrooms'].required = False
def clean_image(self):
image = self.cleaned_data.get('image')
if image:
# Check if the image size exceeds 1MB
if image.size > 1024 * 1024: # 1MB in bytes
# Open the image using Pillow
with Image.open(image) as img:
# Reduce the image size while preserving the aspect ratio
max_width = 1920
max_height = 820
img.thumbnail((max_width, max_height), Image.ANTIALIAS)
# Save the modified image with reduced quality to achieve a smaller file size
buffer = BytesIO()
img.save(buffer, format='JPEG', optimize=True, quality=85)
while buffer.tell() > 1024 * 1024: # Check if file size exceeds 1MB
quality -= 5
if quality < 5:
break
buffer.seek(0)
buffer.truncate(0)
img.save(buffer, format='JPEG', optimize=True, quality=quality)
buffer.seek(0)
image.file = buffer
# Check file extension for allowed formats
allowed_formats = ['gif', 'jpeg', 'jpg']
ext = image.name.split('.')[-1].lower()
if ext not in allowed_formats:
raise forms.ValidationError("Only GIF, JPEG, and JPG images are allowed.")
else:
raise forms.ValidationError("Please upload an image before submitting the form.")
return image
希望这能帮助你。
英文:
I am working a Django project where I want to reduce the image size to be less than 300kb and crop the images to be 1280px 820px. The aim is to make sure every image uploaded is the same irrespective of the initial so any best solution would be appreciated.
Below is what I have tried but nothing works.
ALLOWED_EXTENSIONS = ('.gif', '.jpg', '.jpeg')
class PropertyForm(forms.ModelForm):
description = forms.CharField(label='Property Description:', max_length=60, widget=forms.TextInput(attrs={'placeholder': 'Briefly Describe your Property. E.g. Bedroom & Palour with Private Detached Bathroom'}))
state = forms.ChoiceField(choices=Property.STATE_CHOICES, required=False)
state_lga = forms.CharField(label = 'Local Govt. Area:', max_length=12, widget=forms.TextInput(attrs={'placeholder': 'Enter Local Govt. of Property.'}))
address = forms.CharField(label = 'Property Address:', max_length=60, widget=forms.TextInput(attrs={'placeholder': 'Enter Street Name with Number and Town Name only.'}))
class Meta:
model = Property
fields = ('description', 'address', 'country', 'state', 'state_lga', 'property_type', 'bedrooms', 'bathroom_type', 'price', 'is_available', 'image')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['bedrooms'].required = False
def clean_image(self):
image = self.cleaned_data.get('image')
if image:
# Check if the image size exceeds 1MB
if image.size > 1024 * 1024: # 1MB in bytes
# Open the image using Pillow
with Image.open(image) as img:
# Reduce the image size while preserving the aspect ratio
max_width = 1920
max_height = 820
img.thumbnail((max_width, max_height), Image.ANTIALIAS)
# Save the modified image with reduced quality to achieve a smaller file size
buffer = BytesIO()
img.save(buffer, format='JPEG', optimize=True, quality=85)
while buffer.tell() > 1024 * 1024: # Check if file size exceeds 1MB
quality -= 5
if quality < 5:
break
buffer.seek(0)
buffer.truncate(0)
img.save(buffer, format='JPEG', optimize=True, quality=quality)
buffer.seek(0)
image.file = buffer
# Check file extension for allowed formats
allowed_formats = ['gif', 'jpeg', 'jpg']
ext = image.name.split('.')[-1].lower()
if ext not in allowed_formats:
raise forms.ValidationError("Only GIF, JPEG, and JPG images are allowed.")
else:
raise forms.ValidationError("Please upload an image before submitting the form.")
return image
答案1
得分: 0
你可以使用第三方库来处理你想要存档的所有图像相关工作,这样肯定可以使用pypi库。它非常直观和易于使用。
链接在这里。
英文:
If you want to use third party library for handling all stuff of image which you want archive then definitely you can use pypi library. It's very straight forward and easy to use
Link here
答案2
得分: 0
#Models.py
从PIL导入Image
class Property(models.Model):
...
image = models.ImageField(upload_to='properties_image/')
...
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
this_image = Image.open(self.image.path)
width, height = this_image.size
TARGET_WIDTH = 1280
new_height = 820
this_image = this_image.resize((TARGET_WIDTH, new_height), Image.ANTIALIAS)
this_image.save(self.image.path, quality=50)
英文:
One way I can think of is to use PIL. The Code snippet below makes use of Models
instead of forms
but should do the trick
#Models.py
from PIL import Image
class Property(models.Model):
...
image = models.ImageField(upload_to='properties_image/')
...
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
this_image = Image.open(self.image.path)
width, height = this_image.size
TARGET_WIDTH = 1280
new_height = 820
this_image = this_image.resize(TARGET_WIDTH,new_height),Image.ANTIALIAS)
this_image.save(self.image.path,quality=50)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论