0

I've found several helpful posts on here explain how to crop an image with the Pillow library for Python, but cropping a .png with pillow distorts the colors and darkens the picture a bit. I'm using .png because I want to avoid the images getting distorted in processing.

When I run a dummy script that doesn't even do any cropping:

from PIL import Image

with Image.open('test.png') as image:
    image.save('test copy.png')

The resulting copy is ~30% smaller in file size than the original and noticeably darker, if you flip between them in a photo viewer. How do I get Pillow to crop a picture but leave the colors alone? I'd also like to do the same with local blur (for anonymization), apply a blur in one area without altering the rest of the image.

EDIT: Uploaded .png file and discolored copies to https://github.com/Densaugeo/stack-overflow-question/tree/main

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
Densaugeo
  • 55
  • 3
  • Your PNG files probably have a different configuration than what PIL writes by default. The difference is likely the colorspace or an attached color profile in the original PNGs that gets lost. – Cris Luengo Jun 11 '23 at 18:39
  • 1
    In case the issue is related to embedded ICC profile as Cris commented, try to copy the ICC profile from the input to the output: `from PIL import Image, ImageCms` and `with Image.open('test.png') as image:` `image.save('test copy.png', icc_profile=image.info.get('icc_profile'))`. If it's not solving the problem, please add the PNG image to your question. – Rotem Jun 11 '23 at 18:57
  • image.save('test copy.png', icc_profile=image.info.get('icc_profile')) produces the same output as image.save('test copy.png'). Diff shows no difference at all between them. The only tool I've found for seeing color modes is the "file" command, and it shows "8-bit/color RGB" for both. – Densaugeo Jun 11 '23 at 23:43

2 Answers2

2

Your test.png file has a gAMA chunk with value 50994, but your output files do not. They would also need that chunk in order to render with the same colors.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
1

Kudos, and upvotes to @MarkAdler for sleuthing the lack of gAMA chunk. Here is a method of propagating forward the gAMA from one file to another using exiftool:

exiftool -tagsfromfile goodImage.png -gamma brokenImage.png

You can probably do this in Python, by adapting this answer.


Here is another method using pngcheck and pngcrush.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • This seems to work, thanks! Slightly convoluted to need a "copy the lost chunk" step at the end, but it works for now. – Densaugeo Jun 14 '23 at 02:49