2

我已经设法安装(经过大量努力)django-imagekit,现在我可以使用django-imagekit来压缩上传图像的文件大小。

我可以上传 6MB 的图像,当我使用 10 的质量时,django-imagekit会将图像压缩到 230KB(见下文)。

当上传的图像大小为 300Kb、1MB、2MB、3MB 或更大时(我在想一个 if/elseif/else 语句将确认图像的大小并应用较低的质量,图像的大小 (KB) 越大? 10 的文件压缩适用于较大尺寸的图像,但从根本上降低了较小尺寸图像的图像质量,例如 25Kb。

我什至不确定我将如何编写代码以及将实现此目的的代码放在哪里。所以任何帮助将不胜感激。

这是我的相关models.py文件代码:

from imagekit.processors import Adjust, ResizeToFill
from imagekit.models import ProcessedImageField

class NameDetails(models.Model, FillableModelWithLanguageVersion):
    user = models.ForeignKey(User)
    ....
    #name_details_photograph = models.ImageField(upload_to=_get_name_details_photograph_upload_location, null=True, blank=True)
    name_details_photograph = ProcessedImageField(upload_to=_get_name_details_photograph_upload_location, null=True, blank=True, options={'quality': 25}, processors=[Adjust(sharpness=1.1),])
    ....

    def __unicode__(self):
        return unicode(self.user)

编辑:

我试图实现 ProcessedImageField 类的表单字段版本,但这不会上传图像。

这是我在将 models.py 代码更改回图像字段时尝试的表单代码(上面已注释掉):

from imagekit.forms import ProcessedImageField
from imagekit.processors import Adjust, ResizeToFill

class NameDetailsForm(forms.ModelForm):

    def __init__(self, available_languages, language_preference, file_required, *args, **kwargs):
        """
        available_languages should be a valid choices list
        """
        super(NameDetailsForm, self).__init__(*args, **kwargs)
        self.fields['language_code'] = forms.ChoiceField(choices=available_languages, initial=language_preference, label=_('Language'),)
        #self.fields['name_details_photograph'] = forms.FileField(label=_('Photograph'), required=file_required)
        self.fields['name_details_photograph'] = ProcessedImageField(label=_('Photograph'), required=file_required, spec_id='myapp:profile:name_details_photograph', options={'quality': 25}, processors=[Adjust(sharpness=1.1),])

    class Meta:
        model = NameDetails
4

2 回答 2

4

我要提供的解决方案完全未经测试。它基于imagekit库的源代码。

options kwarg类使用将ImageSpec其传递给 PIL 的Image.save().

因此,对于动态options,您可以创建自己的Spec类,定义options为 aproperty并使用getter来返回一个 on-the-fly options。就像是:

from imagekit import ImageSpec
from imagekit.processors import Adjust, ResizeToFill

class ThumbnailSpec(ImageSpec):
    format = 'JPEG'
    options={'quality': 50}
    processors=[Adjust(sharpness=1.1),]

    @property
    def options(self):
        options = self._options
        #You can create some checks here and choose to change the options
        #you can access the file with self.source
        if self.source.size > 2*100*100:
            options['quality'] -= 25
        return options
    @options.setter
    def options(self, value):
        self._options = value

最后使用你ThumbnailSpec的传递给ProcessedImageField

name_details_photograph = ProcessedImageField(
    upload_to=_get_name_details_photograph_upload_location, 
    null=True, 
    blank=True, 
    spec=ThumbnailSpec
)
于 2015-04-10T05:47:25.403 回答
3

您可以创建一个自定义处理器django imagekit然后在您的模型中使用它。处理器将检查图像的大小,然后返回编辑后的图像。像这样的东西-

class ConditionalResizer(object):
    min_size = None  # minimum size to reduce in KB
    def __init__(self, *args, min_size=1000, **kwargs):
        super().__init__(self, *args, **kwargs) # code is for python > 3.0, modify for python < 3.0 as necessary 
        self.min_size = min_size

    def process(self, image):
        size = # code to get size of image
        if size > self.min_size:
            # process the image
            image = # processed image
        return image

然后在你的Form,添加处理器 -

from imagekit.forms import ProcessedImageField
from imagekit.processors import Adjust, ResizeToFill

class NameDetailsForm(forms.ModelForm):

def __init__(self, available_languages, language_preference, file_required, *args, **kwargs):
    """
    available_languages should be a valid choices list
    """
    super(NameDetailsForm, self).__init__(*args, **kwargs)
    self.fields['language_code'] = forms.ChoiceField(choices=available_languages, initial=language_preference, label=_('Language'),)
    #self.fields['name_details_photograph'] = forms.FileField(label=_('Photograph'), required=file_required)
    self.fields['name_details_photograph'] = ProcessedImageField(label=_('Photograph'), required=file_required, spec_id='myapp:profile:name_details_photograph', options={'quality': 25}, processors=[Adjust(sharpness=1.1), ConditionalResize(min_size=1000)])

class Meta:
    model = NameDetails

我尚未测试此代码,但应该能够解决您的问题。如果没有,请告诉我。

您可以在此处找到有关处理器的更多信息 - https://django-imagekit.readthedocs.org/en/latest/#processors

于 2015-04-10T17:57:09.463 回答