Pushing Pixels with Python
For a private project I had to manipulate a bitmap file and access the raw data in order to convert it (into a LDraw file).
The manipulation part could have been done with a “normal” image manipulation program. However since the manipulations were only basic (scale, rotate/ …) and I already had a python script in mind for the converting part, I incorporated the pixel manipulation into the script.
Python does not have a build-in imaging library, but there is Pillow (a fork of the Python Imaging Library PIL) .
Pillow is easy to install via pip.
If you just want to test Pillow or don’t want to mess up your python installation with various libraries this is the point to set up a virtual environment.
You can read about virtualenv in one of my previous blog posts .
Installing Pillow via pip
H:\>pip install Pillow Collecting Pillow Downloading Pillow-5.1.0-cp35-cp35m-win32.whl (1.4MB) 100% |################################| 1.4MB 736kB/s Installing collected packages: Pillow Successfully installed Pillow-5.1.0
Basic image manipulation
In order to manipulate an image, you have to open it first.
Open an image
>>> from PIL import Image >>> tux_image = Image.open('Tux.png') >>> tux_image <PIL.PngImagePlugin.PngImageFile image mode=P size=314x314 at 0x26CBD0> >>>
Once an image is loaded, you can start working with it. Keep in mind that the Image object has a show() method which you can use to look at the image (it will open the corresponding image in your OS default image viewer).
After finishing your image manipulations save the image via the save(fp, format=None, **params) method.
Since the Pillow library has an excellent tutorial , i will list here some of the basic things you can do:
- rotating: Image.rotate(angle, resample=0, expand=0, center=None, translate=None) MONO_END, e.g. MONO_START tux_image.rotate(45)
- resizing: Image.resize(size, resample=0, box=None) MONO_END, e.g. MONO_START tux_image.resize((50, 50), PIL.Image.BICUBIC)
- cropping: Image.crop(box=None) MONO_END, e.g. MONO_START tux_image.crop((20,20,50,50))
Advanced image manipulation
The Image object has also more advanced image manipulation functions available, e.g. applying filter, transformations, et cetera.
The Pillow library contains various other modules which you can use to manipulate or work with an image. Since they have meaningful names I will list only some of them:
- ImageDraw : Draw simple geometric shapes and text onto an image.
- ImageFilter : To be used with Image.filter() .
Accessing the raw pixel data
This can be done with the Image.getpixel(xy) method.
In my project I wanted to loop over all pixels of a resized image and do some calculations. So i ended up with something like the following code.
Looping over pixels
>>> small_tux = img.resize((20,20)) >>> small_tux = small_tux.convert('RGB') >>> w, h = small_tux.size >>> for y in range(h): ... for x in range(w): ... result[x][y] = calculate(small_tux.getpixel((x,y))) ...
With the Pillow library you have a tool for programmatic image manipulation. So for simple tasks there is no need for a full blown image manipulation program.
Since it is a python library it is also well suited for batch operation on larger amounts of images.