Mashu
Mashu

Reputation: 29

How to generate a 500x500 pixel image in PIL with random place but i can choose what colors?

So for example I want the colors red, blue, and yellow in the 500x500 and the placement has to be random. I was looking at some posts and the documentation but couldn't really find it. With the image I'm going to convert it to a pygame surface using "pygame.image.fromstring".

it should be something like this but in 500x500 and the colors only should be randomized with red, blue and yellow, instead of all those random colors enter image description here

Thank You!

Upvotes: 1

Views: 1384

Answers (2)

Mark Setchell
Mark Setchell

Reputation: 207425

If you only want three colours (or any other number under 256) you should consider using a palette image where, rather than storing three bytes for the RGB values of each pixel, you store a single byte which is the index into a palette (or table) of 256 colours. It is much more efficient. See discussion here.

So, the fastest and most memory efficient way is to initialise your image to random integers in range 0..2 and then push in a palette of your 3 colours:

import numpy as np
from PIL import Image

# Make a Numpy array 500x500 of random integers 0, 1 or 2
na = np.random.randint(0, 3, (500,500), np.uint8)

# Convert to PIL Image
im = Image.fromarray(na)

# Push in 3-entry palette with red, blue and yellow:
im.putpalette([255,0,0, 0,0,255, 255,255,0])

# Save
im.save('result.png')

enter image description here


That takes 1ms on my Mac compared to 180ms for iterating over the pixels and choosing one of 3 RGB colours for each, and creates a 50kB palletised output file rather than the 120kB RGB output file you get with the other method.

Upvotes: 1

Alderven
Alderven

Reputation: 8260

You can iterate over each pixel in your image and replace it with randomly selected value from the list of provided colors:

import random
from PIL import Image


def create_image(colors):
    image = Image.new('RGB', (500, 500))
    for x in range(image.width):
        for y in range(image.height):
            image.putpixel((x, y), random.choice(colors))
    image.save('image.png')


create_image(colors=[(255, 0, 0), (0, 0, 255), (255, 255, 0)])

Output:

red, blue and yellow

Upvotes: 2

Related Questions