Get pixel's RGB using PIL
Is it possible to get the RGB color of a pixel using PIL? I'm using this code:
im = Image.open("image.gif")
pix = im.load()
print(pix[1,1])
However, it only outputs a number (e.g. 0
or 1
) and not three numbers (e.g. 60,60,60
for R,G,B). I guess I'm not understanding something about the function. I'd love some explanation.
Thanks a lot.
Solution 1:
Yes, this way:
im = Image.open('image.gif')
rgb_im = im.convert('RGB')
r, g, b = rgb_im.getpixel((1, 1))
print(r, g, b)
(65, 100, 137)
The reason you were getting a single value before with pix[1, 1]
is because GIF pixels refer to one of the 256 values in the GIF color palette.
See also this SO post: Python and PIL pixel values different for GIF and JPEG and this PIL Reference page contains more information on the convert()
function.
By the way, your code would work just fine for .jpg
images.
Solution 2:
GIFs store colors as one of x number of possible colors in a palette. Read about the gif limited color palette. So PIL is giving you the palette index, rather than the color information of that palette color.
Edit: Removed link to a blog post solution that had a typo. Other answers do the same thing without the typo.
Solution 3:
An alternative to converting the image is to create an RGB index from the palette.
from PIL import Image
def chunk(seq, size, groupByList=True):
"""Returns list of lists/tuples broken up by size input"""
func = tuple
if groupByList:
func = list
return [func(seq[i:i + size]) for i in range(0, len(seq), size)]
def getPaletteInRgb(img):
"""
Returns list of RGB tuples found in the image palette
:type img: Image.Image
:rtype: list[tuple]
"""
assert img.mode == 'P', "image should be palette mode"
pal = img.getpalette()
colors = chunk(pal, 3, False)
return colors
# Usage
im = Image.open("image.gif")
pal = getPalletteInRgb(im)
Solution 4:
Not PIL, but imageio.imread
might still be interesting:
import imageio
im = scipy.misc.imread('um_000000.png', flatten=False, mode='RGB')
im = imageio.imread('Figure_1.png', pilmode='RGB')
print(im.shape)
gives
(480, 640, 3)
so it is (height, width, channels). So the pixel at position (x, y)
is
color = tuple(im[y][x])
r, g, b = color
Outdated
scipy.misc.imread
is deprecated in SciPy 1.0.0 (thanks for the reminder, fbahr!)
Solution 5:
With numpy :
im = Image.open('image.gif')
im_matrix = np.array(im)
print(im_matrix[0][0])
Give RGB vector of the pixel in position (0,0)