2012-12-02 4 views
14

Kann nicht herausfinden, warum das Dokumentprofil auf einer Zuschneidung geändert, skaliert und mit PIL gespeichert wird. Habe mit einem Bild getestet, das sRGB als Farbprofil hatte und nachdem es RGB untagging hat.Python PIL - Ändern des Farbprofils in ungetaggtes RGB beim Zuschneiden, Skalieren und Speichern

Ich versuche PIL zu bekommen, um die skalierte Version mit dem gleichen Farbprofil wie das Originalbild zu speichern.

EDIT: dies Nach ihrem http://comments.gmane.org/gmane.comp.python.image/3215 möglich sein soll, aber noch nicht für mich arbeitet mit 1.1.7 PIL

+0

Haben Sie sich den Patch angesehen, der in der ersten Antwort der verlinkten Diskussion erwähnt wurde? Es ist notwendig, dass die Farbprofilerhaltung funktioniert, nur das Aktualisieren der PIL-Version ist nicht genug (in meiner Antwort unten verwendete ich auch 1.1.7 und hatte das gleiche Problem). – mgibsonbr

+1

@mgibsonbr Wie ich dann sehen kann sind laut der Readme-Datei im Hack von Florian Hoech keine weiteren Bibliotheken nötig. Und in 1.1.7 sollte der Hack zu einem Feature nach http://hg.effbot.org/pil-117/commits/03e996c3b271fd3dabb008a8c694b82e3e6c5917 – Christoffer

Antwort

14

PIL hat eine Funktion zum Lesen des icc_profile und auch eine Möglichkeit zum Speichern mit icc_profile. Also, was ich tat, war die Datei zu öffnen, um die icc_profile zu erhalten:

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

Und fügen Sie ihn in die Datei wieder auf sparen:

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

Und der vollständige Code:

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 

Ich habe sowohl mit getaggten (mit ICC-Profil) als auch mit unmarkierten JPEG-Bildern getestet.

6

Update: Disregard diese Antwort ist @Christoffer's answer die richtige. Wie sich herausstellte, hat load keine Konvertierungen vorgenommen, das ICC-Profil wurde gerade woanders gespeichert.


Ich glaube nicht, entweder dieser Operationen das Farbprofil ändern sich, aber das Wandlungsrecht auf load getan wird. Nach dem Öffnen this sample image mit einer aktuellen Version von PIL (1.1.7 unter Windows XP), wird sofort in RGB umgewandelt:

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

Wenn ich versuche, es so, wie es (ohne etwas zu ändern) ist zu retten zurück, einig Qualität ist verloren. Wenn ich ein verlustfreies Format OTOH verwenden, sieht das resultierende Bild gut zu mir:

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

Der Versuch, das resultierende Bild zurück zu sRGB konvertiert hat nicht funktioniert:

>>> 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 

Ich glaube, in sRGB Speichern würde benötigen Sie eine externe Bibliothek, wie pyCMS oder LittleCMS. Ich habe sie nicht selbst ausprobiert, aber hier ist eine tutorial (mit dem letzteren Tool), die vielversprechend aussieht. Schließlich, hier ist eine discussion thread über das gleiche Problem, das Sie konfrontiert sind (das Farbprofil intakt beim Laden/Speichern), hoffentlich kann es Ihnen einige weitere Hinweise geben.

+0

gemacht worden sein. Das Farbprofil wird auf dem Bild geändert, wenn es den Server trifft, also es ist nicht geladen, wenn ich dich richtig verstehe. Aber dann sollte es im im = PIL sein.Öffne (Bild) in meinem Code, dass das Farbprofil geändert wird. – Christoffer

+0

@Christoffer Haben Sie den Modus von 'im' direkt nach dem Öffnen ausgedruckt? In meinen Tests (siehe erstes Snippet) ändert es sich sofort zu "RGB", also denke ich immer noch, dass es geladen ist. BTW, nachdem Sie näher zu Ihrem Code geschaut haben, öffnen Sie zuerst "image", erstellen die Variable "im", aber dann "image" selbst ("im" wird verworfen). Ist das richtig? – mgibsonbr

+1

Denken Sie nicht, dass sRGB ein Modus in sich selbst ist, sondern nur eine Version des Modus RGB. Wenn Sie also das Farbprofil überprüfen müssen, müssen Sie im.info.get ("icc_profile") loggen. Du hast recht Ich verwerfe den ersten IM. Ich bin mir nicht sicher, warum es dort war, da ich den Code eines anderen repariere. Aber wie du in der Lösung sehen kannst, habe ich es jetzt benutzt;) – Christoffer

Verwandte Themen