Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loads different pixel values on Windows vs Linux #3833

Closed
mikeobr opened this issue May 7, 2019 · 9 comments
Closed

Loads different pixel values on Windows vs Linux #3833

mikeobr opened this issue May 7, 2019 · 9 comments
Labels
Anaconda Issues with Anaconda's Pillow JPEG Linux Windows

Comments

@mikeobr
Copy link

mikeobr commented May 7, 2019

What did you do?

Loaded an image and checked a pixel value.

What did you expect to happen?

Identical values on windows and linux.

What actually happened?

Values differed by a visible amount.

What are your OS, Python and Pillow versions?

  • OS: Windows 10, Amazon Linux
  • Python: 3.7
  • Pillow: 6.0.0
from PIL import Image
import numpy as np
import cv2

test = Image.open("test.jpg")
print(Image.core.jpeglib_version)
print(np.array(test)[35][97])
print(cv2.imread("test.jpg")[35][97][::-1])
# output on windows 10, python 3.7, Pillow 6.0.0
# 6.2
# [188  87 145]
# [188  87 145]

# output on linux, python 3.7, pillow 6.0.0, cv2 is the same, pillow differs
# 9.0
# [196  83 147]
# [188  87 145]

test

Additional Debug info

The input image has an sRGB color profile.

Based on what I've read online, this is may be related to the jpeglib version. However I'm confused about how Pillow links to this dependency and uses it. I'm a little stuck as to how to make the code consistent between os + versions.

@radarhere
Copy link
Member

How did you install Pillow on Windows and Linux? If you are just interested in consistency, the simplest thing might be to install jpeg 6.2 on Linux.

@mikeobr
Copy link
Author

mikeobr commented May 8, 2019

Pillow was installed just via pip install Pillow.

I am interested in consistency, but the 6.2 jpeglib also seems pretty inaccurate, maybe it is ignoring the color profiles and the outputs are perceivably different.

I tried using this conda environment on windows: https://anaconda.org/anaconda/pillow. It has version 9 jpeglib and produces results in line with what I saw on Linux.

@radarhere radarhere changed the title Pixel loads different pixel values on windows vs linux Pixel loads different pixel values on Windows vs Linux May 10, 2019
@aclark4life aclark4life added Bug Any unexpected behavior, until confirmed feature. Linux Windows labels May 11, 2019
@cgohlke
Copy link
Contributor

cgohlke commented Sep 5, 2019

The Windows wheels are built with libjpeg-turbo-2.0, which emulates the libjpeg v6b API/ABI by default. libjpeg-turbo can be compiled for the v7 or v8 API/ABI, but not v9.

@albert-92
Copy link

Will there be a fix any time soon?

@envil
Copy link

envil commented Feb 12, 2020

I encounter the same problem. Step to reproduce:

  1. Read an image on Windows and Linux/UNIX:
def image_from_data(image_data: bytes) -> Image:
    buffer = io.BytesIO(image_data)

    return Image.open(buffer)
  1. Save the pickles of both versions of Pillow image objects:
# on Windows
pickle.dump(image_windows, open('image_windows.pickle', 'wb'))

# on Linux/UNIX
pickle.dump(image_linux, open('image_linux.pickle', 'wb'))
  1. Compare both images:
image_diff = ImageChops.logical_xor(image_windows.convert('1'), image_linux.convert('1'))
image_diff.show()

Here's the result:
penguin

Black dots mean similar, white dots means different.

We've tried to use the same python version, Pillow version but the results are still the same.

@cgohlke
Copy link
Contributor

cgohlke commented Feb 12, 2020

As mentioned before, the Windows wheels are built with libjpeg-turbo, the Linux wheels are not. JPEG decoders are allowed to produce slightly different results, "a maximum of one bit of difference for each pixel component" according to Wikipedia.

@radarhere
Copy link
Member

For more discussion on this, see #4686

@radarhere radarhere changed the title Pixel loads different pixel values on Windows vs Linux Loads different pixel values on Windows vs Linux Mar 22, 2021
@radarhere radarhere added JPEG and removed Bug Any unexpected behavior, until confirmed feature. labels Mar 22, 2021
@radarhere
Copy link
Member

Closing, as the conclusion here is that there should not be an expectation for different JPEG decoders to produce the same results.

If you want to ensure the same output, please ensure you are using the same version of libjpeg on both environments. If the Pillow wheel does not have the version of libjpeg that you require, then install it and try compiling Pillow from source. Compiling on Windows became easier after the opening of this issue, thanks to #4495.

@martinbenes1996
Copy link

A relevant read to this is following research paper:

https://dl.acm.org/doi/pdf/10.1145/3531536.3532962

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Anaconda Issues with Anaconda's Pillow JPEG Linux Windows
Projects
None yet
Development

No branches or pull requests

7 participants