views:

4392

answers:

6

If i open an image with open("image.jpg"), how can i get the rgb values of a pixel, if i have the 'coordinates' ( or co-ordinates?) of the pixel?

Then how can i do the reverse of this? Starting with a blank graphic, 'write' a pixel with a certain rgb value?

It would be so much better if i didn't have to download any additional libraries

+2  A: 

I think the Python Image Library would help here

PIL

Dean
A: 

Image manipulation is a complex topic, and it's best if you do use a library. I can recommend gdmodule which provides easy access to many different image formats from within Python.

Greg Hewgill
+18  A: 

It's probably best to use the Python Image Library to do this which I'm afraid is a separate download.

The easiest way to do what you want is via the load() method on the Image object which returns a pixel access object which you can manipulate like an array:

pix = im.load()
print pix[x,y]
pix[x,y] = value

Alternatively, look at ImageDraw which gives a much richer API for creating images.

Dave Webb
+1  A: 

There's a really good article on wiki.wxpython.org entitled Working With Images. The article mentions the possiblity of using wxWidgets (wxImage), PIL or PythonMagick. Personally, I've used PIL and wxWidgets and both make image manipulation fairly easy.

Jon Cage
Note that your link doesn't show up properly.
Paul Stephenson
Thanks; for some reason it worked fine on the preview but not on the fully-posted version!
Jon Cage
+2  A: 

PyPNG - lightweight PNG decoder/encoder

Although the question hints at JPG, I hope my answer will be useful to some people.

Here's how to read and write PNG pixels using PyPNG module:

import png, array

point = (2, 10) # coordinates of pixel to be painted red

reader = png.Reader(filename='image.png')
w, h, pixels, metadata = reader.read()
pixel_byte_width = 4 if metadata['has_alpha'] else 3
pixel_position = point[0] + point[1] * w
new_pixel_value = (255, 0, 0, 0) if metadata['has_alpha'] else (255, 0, 0)
pixels[
  pixel_position * pixel_byte_width :
  (pixel_position + 1) * pixel_byte_width] = array.array('B', new_pixel_value)

output = open('image-with-red-dot.png', 'wb')
writer = png.Writer(w, h, **metadata)
writer.write_array(output, pixels)
output.close()

PyPNG is a single pure Python module roughly 1000 lines of code long.

PIL is a more comprehensive imaging library, but it's also significantly heavier.

Constantin
+1  A: 

You can use pygame's surfarray module. This module has a 3d pixel array returning method called pixels3d(surface). I've shown usage below:

from pygame import surfarray, image, display
import pygame
import numpy #important to import

pygame.init()
image = image.load("myimagefile.jpg") #surface to render
resolution = (image.get_width(),image.get_height())
screen = display.set_mode(resolution) #create space for display
screen.blit(image, (0,0)) #superpose image on screen
display.flip()
surfarray.use_arraytype("numpy") #important!
screenpix = surfarray.pixels3d(image) #pixels in 3d array:
#[x][y][rgb]
for y in range(resolution[1]):
    for x in range(resolution[0]):
        for color in range(3):
            screenpix[x][y][color] += 128
            #reverting colors
screen.blit(surfarray.make_surface(screenpix), (0,0)) #superpose on screen
display.flip() #update display
while 1:
    print finished

I hope been helpful. Last word: screen is locked for lifetime of screenpix.