43

Suppose I have a list of pixels (represented as tuples with 3 RGB values) in a list that looks like list(im.getdata()), like this:

[(0,0,0),(255,255,255),(38,29,58)...]

How do I create a new image using RGB values (each tuple corresponds to a pixel) in this format?

Thanks for your help.

Amit
  • 981
  • 2
  • 9
  • 16
  • I tried using `im.paste()` but it gave me the following error: "SystemError: New style getargs format but argument is not a tuple" – Amit Aug 21 '12 at 20:59

3 Answers3

64

You can do it like this:

list_of_pixels = list(im.getdata())
# Do something to the pixels...
im2 = Image.new(im.mode, im.size)
im2.putdata(list_of_pixels)
Aleksi Torhamo
  • 6,452
  • 2
  • 34
  • 44
14

You can also use scipy for that:

#!/usr/bin/env python

import scipy.misc
import numpy as np

# Image size
width = 640
height = 480
channels = 3

# Create an empty image
img = np.zeros((height, width, channels), dtype=np.uint8)

# Draw something (http://stackoverflow.com/a/10032271/562769)
xx, yy = np.mgrid[:height, :width]
circle = (xx - 100) ** 2 + (yy - 100) ** 2

# Set the RGB values
for y in range(img.shape[0]):
    for x in range(img.shape[1]):
        r, g, b = circle[y][x], circle[y][x], circle[y][x]
        img[y][x][0] = r
        img[y][x][1] = g
        img[y][x][2] = b

# Display the image
scipy.misc.imshow(img)

# Save the image
scipy.misc.imsave("image.png", img)

gives

enter image description here

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
7

Here's a complete example since I didn't get the trick at first.

from PIL import Image

img = Image.new('RGB', [500,500], 255)
data = img.load()

for x in range(img.size[0]):
    for y in range(img.size[1]):
        data[x,y] = (
            x % 255,
            y % 255,
            (x**2-y**2) % 255,
        )

img.save('image.png')

output

And if you're looking for grayscale only, you can do Image.new('L', [500,500], 255) and then data[x,y] = <your value between 0 and 255>

damio
  • 6,041
  • 3
  • 39
  • 58