2016-02-15 15 views
5

私はPillowDjango、およびdjango-imagekitと作業しています。イメージを特定のファイルサイズに変換するにはどうすればよいですか?

画像を取得し、JPEGに変換し、150x150にトリミングし、ファイルサイズを5KBにするプロファイル画像モデルフィールド(画像キットのProcessedImageFieldクラスを使用している可能性があります)が必要です。

profile_picture = imagekit.models.ProcessedImageField(upload_to=get_profile_picture_file_path, 
                 format='JPEG', 
                 processors=[ResizeToFill(height=150, width=150)] 
                ) 

しかし、どのように私は、ファイルサイズが5キロバイトであることを確認することができます

最初の二つは簡単ですか?私はProcessedImageFieldoptions={'quality': 60}パラメータのようなものを使うことができましたが、それは私の知る限り、元のファイルサイズとの相対的な関係にあるようです。

解決策はdjango-imagekitを使用する必要はありませんが、それが望ましいでしょう。

答えて

0

多分このように。アップロードされた後に画像のサイズを確認し、それを削除するか、上書きsave方法により減少:

class Images(models.Model): 
    profile_picture = imagekit.models.ProcessedImageField(upload_to=get_profile_picture_file_path, 
                format='JPEG', 
                processors=[ResizeToFill(height=150, width=150)] 
               ) 

    def save(self, force_insert=False, force_update=False, using=None, 
      update_fields=None): 

     if os.stat(get_profile_picture_file_path + "/" + self.profile_picture.new_name).st_size > max_size: 
      do_something_further_image_processing_to_decrease_size 

     super(Images, self).save() 
+0

これは、ファイルが大きすぎることを確認することで良いスタートですが、do_something_further_image_processing_to_decrease_size' '内のロジックは本当に問題の関連する部分です。どのようにしてファイルのサイズを(解像度/ JPEGの解像度の異なる画像でも)いつでも特定のサイズに縮小することができますか? – dcgoss

+0

ここでは、反復ごとに生成された画像の現在のサイズに対応する解像度を10%またはその他の因子で減少させる反復関数をここに追加します。 'PIL'はあなたにこのような可能性を与えます。 – Magnar

0

私は同様の問題を持っていたので、私は(jpegoptim、optipng、など)OSツールを使用して画像を最適化することを決定しましたシグナルを使ってモデルを保存した後にdjangoから呼び出されます(オーバーライドされたsaveメソッドも可能です)。このツールは、画像からメタデータを最適化し、削除します。一方、150x150のjpgファイルの平均圧縮率とサイズを調べて、セットアップに最高の品質を推測しようとすると、これを確認できます:(jpeg compression ratio

これは、保存した後、私に信号を与える簡単なサムネイル画像ライブラリ使用してメートル:

@receiver(saved_file) 
def optimize_file(sender, fieldfile, **kwargs): 
    optimize(fieldfile.path) 


# thumbnail optimization 
@receiver(thumbnail_created) 
def optimize_thumbnail(sender, **kwargs): 
    optimize(sender.path) 

def optimize(path): 
    """ 
    install image utilities 
    apt-get install jpegoptim optipng pngcrush advancecomp 
    :param path: 
    :return: 
    """ 
    # taken from trimage (http://trimage.org/) 
    runString = { 
     ".jpeg": u"jpegoptim -f --strip-all '%(file)s' ; chmod 644 '%(file)s'", 
     ".jpg": u"jpegoptim -f --strip-all '%(file)s' ; chmod 644 '%(file)s'", 
     ".png": u"optipng -force -o7 '%(file)s' && advpng -z4 '%(file)s' && pngcrush -rem gAMA -rem alla -rem cHRM -rem iCCP -rem sRGB -rem time '%(file)s' '%(file)s.bak' && mv '%(file)s.bak' '%(file)s' ; chmod 644 '%(file)s'" 
    } 

    ext = splitext(path)[1].lower() 
    if ext in runString: 
     subprocess.Popen(runString[ext] % {'file': path}, shell=True)