Reputation: 7243
I'm using PIL and Image modes in Python. I want to create an image with this code:
imagesize = (12,12)
image = Image.new("RGB",imagesize,color=None)
I will use this function to put pixels on my image:
.putpixel(xy, color)
color is in a list of tuples. For exemple:
RGB = [((255, 255, 255),(207, 103, 36),(204, 93, 21),(204, 93, 21),(204, 93, 21), (.......some more RGB tuples.....)]
I need a loop that in .putpixel(xy, color):
color is incremented one step every time. For example RGB[0], next loop RGB[1] and so on. While this loop is being made the x and y is the more difficult to me. x goes from 1 to 12 (image size) while y is 0 and then, when x reaches imagesize it returns to 1 to 12 but y is now 1. The loop is ended when x and both reach to the end of image size.
Can anyone help me? I'm new in Python.
Regards,
Favolas
EDIT
P:S - Forgot to say that since this is for a school project I cant use any methods besides img.new, img.show and img.outpixel
Upvotes: 5
Views: 9519
Reputation: 2076
If we have these two lists:
xy = [(1,2),(3,4),(5,6),(7,8)]
rgb = [(0,0,255), (0,255,0), (255,0,0), (255,255,0), (255,255,255)]
We can map the XY list to the RGB list into a dictionary:
d = dict(zip(xy,rgb))
Which looks like this:
>>> print(d)
{(1, 2): (0, 0, 255), (5, 6): (255, 0, 0), (3, 4): (0, 255, 0), (7, 8): (255, 255, 0)}
So we now have a dictionary, the key is the XY and the value is the corresponding RGB. Now we can map these key-value pairs using list comprehension:
[putpixel(x,col) for x,col in d.items()]
As a test, a mock putpixel() method that prints the inputs verify the results:
def putpixel(xy,col):
print('%s set to %s' % (xy,col))
>>> result = [putpixel(x,col) for x,col in d.items()]
(1, 2) set to (0, 0, 255)
(5, 6) set to (255, 0, 0)
(3, 4) set to (0, 255, 0)
(7, 8) set to (255, 255, 0)
List comprehension usually returns a list of processed items, in this case we don't return a result from putpixel(), thus our result list would contain empties.
Upvotes: 1
Reputation: 28703
It depends on how you want to put RGB colors. For example:
for y in range(12):
for x in range(12):
img.putpixel(x, y, RGB[(x + 12*y)%len(RBG)]
will put 0 to N RBG colors in 0 to N pixels, 0 to N RGBs to 0+N, 2N pixels and so on. There are another options - choose the color randomly:
import random
...
for y in range(12):
for x in range(12):
img.putpixel(x, y, RBG[random.randint(0, len(RGB)-1)]
Optimization for both cases is left as an exercise.
Upvotes: 1
Reputation: 94162
If you have nested loops, i from 0 to 11 and j from 0 to 11, then to index incrementally into a one-dimensional vector you need to get X[j + i * 11].
>>> for i in range(5):
... for j in range(5):
... print j + i*5
will print 0 to 24.
See other answers for better ways to fill Images, and there are probably more pythonic ways of doing this too. But this is the generic answer!
Note this is for variables that start at ZERO, not ONE. For your 12x12 pixel image the valid xy range is from 0 to 11.
Upvotes: 1
Reputation: 32919
Ok, my comment from above should've really gone into an answer. I should catch some sleep. You can basically just put your pixel data into the image at once. The putdata
method of a PIL.Image accepts a list of tuples that make up the pixels of the images. So:
img = PIL.Image.new("RGB", (12, 12))
img.show() # see a black image
pixels = [(255,0,0)]*(12*12)
img.putdata(pixels)
img.show() # see a red image
Upvotes: 2