2012-12-02 27 views
14

クロップ時にドキュメントプロファイルが変更され、PILで保存される理由を理解できません。カラープロファイルとしてsRGBを持つ画像と、タグなしのRGBを持つ画像でテストしました。Python PIL - クロップ、スケール、保存時にカラープロファイルをタグなしRGBに変更する

def scale(self, image): 
    images = [] 

    image.seek(0) 

    try: 
     im = PIL.open(image) 
    except IOError, e: 
     logger.error(unicode(e), exc_info=True) 

    images.append({"file": image, "url": self.url, "size": "original"}) 

    for size in IMAGE_WEB_SIZES: 
     d = cStringIO.StringIO() 
     try: 
      im = crop(image, size["width"], size["height"]) 
      im.save(d, "JPEG") 
      images.append({"file": d, "url": self.scale_url(size["name"]), "size": size}) 
     except IOError, e: 
      logger.error(unicode(e), exc_info=True) 
      pass 

    return images 

元の画像と同じカラープロファイルで拡大縮小版を保存しようとしています。

EDIT:これによると、それはhttp://comments.gmane.org/gmane.comp.python.image/3215可能なはずですが、それでも更新PIL 1.1.7に

+0

リンクディスカッションの最初の返信に記載されているパッチを見ましたか? PILのバージョンを更新するだけでは不十分です(下記の私の答えでは、私も1.1.7を使用していて、同じ問題がありました)。 – mgibsonbr

+1

@mgibsonbr Florian HoechのハックのReadmeファイルによれば、他のライブラリは必要ありません。 1.1.7では、http://hg.effbot.org/pil-117/commits/03e996c3b271fd3dabb008a8c694b82e3e6c5917 – Christoffer

答えて

14

PILには、icc_profileを読み取る機能とicc_profileで保存する機能があります。

try: 
    im1 = PIL.open(image) 
    icc_profile = im1.info.get("icc_profile") 

してSaveを再度ファイルに追加:

im.save(d, "JPEG", icc_profile=icc_profile) 

とフルコード:だから私がやったことはするICC_Profileを取得するために、ファイルを開くことだった

def scale(self, image): 
    images = [] 

    image.seek(0) 

    try: 
     im1 = PIL.open(image) 
     icc_profile = im1.info.get("icc_profile") 
    except IOError, e: 
     logger.error(unicode(e), exc_info=True) 

    images.append({"file": image, "url": self.url, "size": "original"}) 

    for size in IMAGE_WEB_SIZES: 
     d = cStringIO.StringIO() 
     try: 
      im = crop(image, size["width"], size["height"]) 

      im.save(d, "JPEG", icc_profile=icc_profile) 
      images.append({"file": d, "url": self.scale_url(size["name"]), "size": size}) 
     except IOError, e: 
      logger.error(unicode(e), exc_info=True) 
      pass 

    return images 

私はタグ付き(iccプロファイル付き)とタグなしのJPEG画像の両方でテストしました。

6

を使用して私のために働いていない:@Christoffer's answerが正しいものである、この答えを無視してください。判明したように、loadはコンバージョンを行っていないため、ICCプロファイルは他の場所に保存されていました。


私は、これらの操作のいずれかがカラープロファイルを変更しているとは思いませんが、変換は、右loadに行われています。 PIL(Windows XPの上1.1.7)の最新バージョンを使用してthis sample imageを開いた後、それはすぐにRGBに変換されます。

>>> from PIL import Image 
>>> Image.open('Flower-sRGB.jpg') 
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=600x450 at 0xD3D3F0> 

私はそれが(何も変更せずに)ある方法でそれをバック保存しようとすると、いくつかの品質は失われます。私は大藤ロスレス形式を使用している場合は、結果の画像は、私には罰金になります。

>>> im = Image.open('Flower-sRGB.jpg') 
>>> im.save("Flower-RBG.jpg") 
>>> im.save("Flower-RBG.png") 

が機能しなかったバックのsRGBへの結果の画像を変換しようとすると:

>>> im = Image.open('Flower-sRGB.jpg').convert('CMYK') 
>>> im 
<PIL.Image.Image image mode=CMYK size=600x450 at 0xD73F08> 
>>> im.save("Flower-CMYK.png") 

>>> im = Image.open('Flower-sRGB.jpg').convert('sRGB') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Python27\lib\site-packages\PIL\Image.py", line 702, in convert 
    im = im.convert(mode, dither) 
ValueError: conversion from RGB to sRGB not supported 

を私がsRGBに保存信じますpyCMSまたはLittleCMSのような外部ライブラリが必要です。私は自分で試したことはありませんが、有望に見えるのはtutorialです(後者のツールを使用しています)。最後に、あなたが直面している同じ問題に関するdiscussion threadがあります(ロード/保存時にカラープロファイルをそのままにしておきましょう)。

+0

に基づいてハッキングが行われているはずです。イメージがサーバーに当たったときにカラープロファイルが変更されるため、私はあなたのことを正しく理解していれば負荷がかかりません。しかしそれはim = PILにあるはずです。自分のコードでカラープロファイルが変更された(イメージ)を開きます。 – Christoffer

+0

@Christofferあなたはそれを開いた直後に 'im'のモードを印刷/ログアウトしましたか?私のテスト(最初のスニペットを参照)では、すぐに 'RGB'に変更されますので、まだロード中だと思います。ところで、あなたのコードに密接に目を向けると、まず 'image'を開いて変数' im'を作成しますが、 'image'自体を作っています(' im'を破棄します)。そうですか? – mgibsonbr

+1

sRGBはそれ自身のモードではなく、モードRGBの単なるバージョンだとは思わないでください。したがって、カラープロファイルをチェックする必要がある場合は、im.info.get( "icc_profile")をログに記録する必要があります。あなたは正しいです、私は最初のIMを捨てます。なぜ他の人のコードを修正しているのかわからない。しかし、あなたがソリューションで見ることができるように、私は今それを使用していることがわかりました;) – Christoffer

関連する問題