I’ll level with you. I rarely need to manipulate specific pixels in an image, but when those occasions come along, it’s a massive pain in the neck. One that’s preventable with Python. So here it is. A quick starter guide to coding pixel by pixel adjustments.
The Set Up
Ok, let’s start off by installing the Pillow module. I hate installing modules through the command prompt, so I use the Python shell. Here’s what I typed in to make that happen:
A Simple Shell Script
To make sure Pillow installed properly, try popping this into the Python shell. Remember, when you’re specifying a file path in Python, you’ll need to double up on your back slashes. Use .open to stash your tester image into a variable, and then append .size to get the width and height out.
Print RGBA Values for Every Pixel
The width and height will be returned as a tuple. To make the script adaptable, you’ll want to assign width and height variables. Accessing values in a tuple is just a matter of referencing the appropriate position within brackets. The x value is at 0, and the y is at 1.
*Tuples, because they are the devil, start counting at 0*
Once you’ve called .load, you can access the red, green, blue, and alpha values using a nested loop like so:
from PIL import Image im = Image.open('C:\\Users\\Li\\Desktop\\HexTest.png') pix = im.load() width = im.size[0] height = im.size[1] for y in range(height): for x in range(width): print(pix[x,y])
Keep in mind, if your image is 700 by 800, this is going to loop through 560,000 pixels. It might take a while.
Find the Black Pixels
What’s fun about this is when you combine that last script with an if statement, you can get a list of coordinates with a specific color.
Accessing Red, Green, and Blue Values Separately
Alright, what if you don’t want to find pixels at a specific RGB value, but more or less than a value?
See that pix[x,y] line above? That returns a tuple made up of four values. Meaning you can access each of those values separately in the normal access-a-tuple fashion. It’s going to look a little hokey with brackets on top of brackets, but all you really need to remember is red is in the [0] slot of the tuple, green is at [1], blue is at [2], and alpha is at [3].
So, say, if you wanted to have your if statement look specifically for pixels that have a red value less than 50, you could use a this expression:
if pix[x,y][0] < 50:
The full Python script is over at gist.
Here’s a look at what those results look like with different values plugged in:
*Scripts tested in Python 3.6