Pablo Pardo
Pablo Pardo

Reputation: 11

Different pixel values loading an image from stream in python2 and python3

I'm migrating some code from python2 to python3 which loads an image from a bytes stream. I need the resulting image to have the exact same values in all its pixels. However with the implementation below both images differ in some pixels on some values of intensity.

Here is the python 2.7 implementation:

from PIL import Image
from cStringIO import StringIO
import requests

img_url = "https://images.unsplash.com/photo-1508921912186-1d1a45ebb3c1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8cGhvdG98ZW58MHx8MHx8&w=1000&q=80"
response = requests.get(img_url)
bytes_data = response.content
stream = StringIO(bytes_data)
img = Image.open(stream)

And here is the python3.8 implementation:

from PIL import Image
from io import BytesIO
import requests

img_url = "https://images.unsplash.com/photo-1508921912186-1d1a45ebb3c1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8cGhvdG98ZW58MHx8MHx8&w=1000&q=80"
response = requests.get(img_url)
bytes_data = response.content
stream = BytesIO(bytes_data)
img = Image.open(stream)

My guess is that the pixel differences come from the stream object, but I don't know much about the topic. (Edit 1)

Edit 1: If the PIL version is the same (2.8.2) in both python2.7 and python3.8 the results are the same. This would point out that the difference comes from the PIL version rather than the python version.

Edit 2: The loaded JPGS start differing at PIL version 9.0.0

Upvotes: 1

Views: 256

Answers (1)

Mark Setchell
Mark Setchell

Reputation: 207465

That stream is JPEG data. JPEG is lossy and implementations of JPEG codecs are permitted to make different approximations and trade-offs in order to prefer performance or speed or compression ratio. Likewise, different versions of the same library are allowed to do so.

My guess would be that you have a different JPEG library version between the 2 environments. You should be able to check with:

python3 -m PIL | grep -i JPEG

and

python2.7 -m PIL | grep -I JPEG

Other ways to see the PIL version:

import PIL
print(PIL.__version__)

Or:

import PIL
print(dir(PIL))

Or from your shell outside your Python interpreter:

pip3 show Pillow

Name: Pillow
Version: 8.4.0
Summary: Python Imaging Library (Fork)
Home-page: https://python-pillow.org
Author: Alex Clark (PIL Fork Author)
Author-email: [email protected]
License: HPND
Location: /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages
Requires: 
Required-by: CairoSVG, imageio, matplotlib

Upvotes: 1

Related Questions