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

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)
In both virtual environments I'm using the same version of PIL (2.8.2) to make sure the differences don't come from there. (Edit 1)
The requests response returns the same, bytes_data is exactly the same bytes string in both implementations.
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

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: aclark#python-pillow.org
License: HPND
Location: /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages
Requires:
Required-by: CairoSVG, imageio, matplotlib

Related

How to convert video on python to .mp4 without ffmpeg?

I need to convert videos to .mp4 format I used to ffmpeg but it converts for too long. Is there are a way to convert video to .mp4 in python without ffmpeg?
UPD moviepy depends on ffmpeg too (
==
Zulko/moviepy
pip install MoviePy
import moviepy.editor as moviepy
clip = moviepy.VideoFileClip("myvideo.avi")
clip.write_videofile("myvideo.mp4")
As per MoviePy documentation, there is no ffmpeg dependencies:
MoviePy depends on the Python modules Numpy, imageio, Decorator, and tqdm, which will be automatically installed during MoviePy's installation.
ImageMagick is not strictly required, but needed if you want to incorporate texts. It can also be used as a backend for GIFs, though you can also create GIFs with MoviePy without ImageMagick.
PyGame is needed for video and sound previews (not relevant if you intend to work with MoviePy on a server but essential for advanced video editing by hand).
For advanced image processing, you will need one or several of the following packages:
The Python Imaging Library (PIL) or, even better, its branch Pillow.
Scipy (for tracking, segmenting, etc.) can be used to resize video clips if PIL and OpenCV are not installed.
Scikit Image may be needed for some advanced image manipulation.
OpenCV 2.4.6 or a more recent version (one that provides the package cv2) may be needed for some advanced image manipulation.
Matplotlib
I wrote a quick program that will convert all video files of a particular type in a directory to another type and put them in another directory.
I had to install moviepy using Homebrew for it to work rather than rely on PyCharm's package installation.
import moviepy.editor as moviepy
import os
FROM_EXT = "mkv"
TO_EXT = "mp4"
SOURCE_DIR = "/Volumes/Seagate Media/Movies/MKVs"
DEST_DIR = "/Volumes/Seagate Media/Movies/MP4s"
for file in os.listdir(SOURCE_DIR):
if file.lower().endswith(FROM_EXT.lower()):
from_path = os.path.join(SOURCE_DIR, file)
to_path = os.path.join(DEST_DIR, file.rsplit('.', 1)[0]) + '.' + TO_EXT
print(f"Converting {from_path} to {to_path}")
clip = moviepy.VideoFileClip(from_path)
clip.write_videofile(to_path)

Rotating a video with Python 3.4

I am using moviepy to try resize a video clip but every time I try I get this error. Can anyone explain how I can fix it? Thanks
My python code
Import everything needed to edit video clips
from moviepy.editor import *
# Load video clip
myclip = VideoFileClip("dog.mov")
myclip.resize( (460,720) ) # New resolution: (460,720)
myclip.write_videofile("resized_clip.mp4") #write new video file
The error
File "/usr/local/lib/python3.4/dist-packages/PIL/Image.py", line 699, in tostring
"Please call tobytes() instead.")
Exception: tostring() has been removed. Please call tobytes() instead.
Looks like you are using PIL, I would try using Pillow, a support fork that is maintained. MoviePY recommends you use Pillow in lieu of Pil in it's docs:
http://zulko.github.io/moviepy/install.html
For advanced image processing you will need one or several of these
packages. For instance using the method clip.resize requires that at
least one of Scipy, PIL, Pillow or OpenCV are installed.
The Python Imaging Library (PIL) or, better, its branch Pillow .

Python +pyodbc Retrieving images from MSSQL data. HOW to?

Sorry I don't show any piece of code here but I simply don't know how to start?
Ok I simply selected image cell and got file of bytearray:
"[bytearray(b'\xff\xd8\xff\xe1\x1a1Exif\x00\x00II*\x00\x08\x00\x00\x00\x10\x00\x00\x01\x03\x00\x01\x00\x00\x00\x08\x01\x00\ (...) etcetc )]"
But how to transform it and save as image?
Here's the answer:
from PIL import Image
import os,io
.....
image = Image.open(io.BytesIO(my_bytearray))
image.save(path_to_image)
PIL must be installed separately by
pip -m install pillow (I'm not certain if -m is necessary ;) )

ImageGrab Python on OS X

I want to use a imageGrab in my application.
My laptop is a macbook with OSX.
When I use Pillow I got this error:
ImportError: ImageGrab is Windows only
Code:
import ImageGrab
im = PIL.ImageGrab.grab()
but in Pillow documentation says:
The current version works on OS X and Windows only.
Take a snapshot of the screen.
The pixels inside the bounding box are returned as an “RGB” image on Windows or “RGBA” on OS X.
If the bounding box is omitted, the entire screen is copied.
http://pillow.readthedocs.org/en/latest/reference/ImageGrab.html
When I use pyscreenshot I got this error:
IOError: cannot identify image file '/var/folders/wk/b1c839t15xvbz923wtfdsfw80000gn/T/pyscreenshot_imagemagick_Gsb0Pw.png'
Code:
import pyscreenshot as ImageGrab
im=ImageGrab.grab()
According to the commit history, OSX support was only added on 1st Aug 2015. However, the latest Pillow release (2.9.0) was made on 1st July 2015. So it would appear that the online documentation is not kept in sync with the current release.
You could compile a pre-release version from github to get the required functionality, but it would probably be much simpler to just copy the relevant ImageGrab code directly:
import os, tempfile, subprocess
from PIL import Image
def grab(bbox=None):
f, file = tempfile.mkstemp('.png')
os.close(f)
subprocess.call(['screencapture', '-x', file])
im = Image.open(file)
im.load()
os.unlink(file)
if bbox:
im = im.crop(bbox)
return im
The next Pillow release, 3.0.0, is due out on Thursday (1st Oct 2015) and ImageGrab will support both OS X and Windows.
The linked documentation is the latest, and is generated from the latest master branch.
The 2.9.0 docs says it's Windows only.
OS X support was added in Pillow 3.3.0.

difference in using the import and from * import statement

When I install PIL http://www.pythonware.com/products/pil/ on 32 bit python, I can use import Image and then use the Image library inside PIL. However, for the 64 bit python, I downloaded http://www.lfd.uci.edu/~gohlke/pythonlibs/. However, when I use import Image, it gives me error, "No Module named Image". However, I can use from PIL import Image.
Why is that I can use import Image directly in one instance and not in another?
You want to install Pillow instead.
It comes in both 32 and 64 bit variants for Windows, and has fixed long-standing issues with the original PIL library.
The PIL library has long been broken when it comes to packaging. Pillow was started as a fork to fix these issues once and for all, and version 2.0.0 added Python 3 support (with a grant from the Python Software Foundation).
They're different libraries. Or, to be specific, they're different packaging of the same library.
PIL is notorious for these sort of issues. Just use Pillow instead.

Categories