2

I want to do the following:

  • Load a png image to the Python code
  • Get the pixel by pixel RGB data in three arrays, one each for R, G and B. I mean R[i,j] should give me the value of R at the i,j th pixel of the image.
  • Once I have the arrays I can always edit data.
  • Plot the edited data using the three array R,G and B and save it as another png image

How to do it in python?

Raz Luvaton
  • 3,166
  • 4
  • 21
  • 36
lovespeed
  • 4,835
  • 15
  • 41
  • 54
  • 1
    See answers here: http://stackoverflow.com/questions/138250/read-the-rgb-value-of-a-given-pixel-in-python-programatically – ojs May 04 '13 at 13:17
  • 1
    @lovespeed. Since you already know the high level of what you want to do, you're half-way there. The other half is trying to do the individual steps. Why not go learn how to load an image in python, and post a question only *after* you get stuck doing that. – jpaugh Aug 21 '17 at 15:35

1 Answers1

8

use PIL to load the image:

from PIL import Image
img = Image.open('yourimage.png')

I'm going to suggest a method that messes directly with the image data, without accessing individual pixels by coordinates.

You can get the image data in one big byte string:

data = img.tostring()

You should check img.mode for the pixel format. Assuming it's 'RGBA', the following code will give you separate channels:

R = data[::4]
G = data[1::4]
B = data[2::4]
A = data[3::4]

If you want to access pixels by coordinate you could do something like:

width = img.size[0]
pixel = (R[x+y*width],G[x+y*width],B[x+y*width],A[x+y*width])

Now to put it back together, there's probably a better way, but you can use zip:

new_data = zip(R,G,B,A)

And reuce:

new_data = ''.join(reduce(lambda x,y: x+y, zip(R,G,B,A)))

Then to save the picture:

new_img = Image.fromstring('RGBA', img.size, new_data)
new_img.save('output.png')

And here's everything together in an example that zeros the red channel:

from PIL import Image
img = Image.open('yourimage.png')

data = img.tostring()
R = data[::4]
G = data[1::4]
B = data[2::4]
A = data[3::4]

R = '\0' * len(R)

new_data = ''.join(reduce(lambda x,y: x+y, zip(R,G,B,A)))
new_img = Image.fromstring('RGBA', img.size, new_data)
new_img.save('output.png')