7

OK. I'm tired of googling and reading throught lots of documentation with no results.

My aim is simple: get pyglet to draw an image pixel by pixel.

I've been searching for hours with no results. Can anyone give an example of a short program that draws in a display specifying the color pixel by pixel? For example: drawing a gradient from black to white.

Jason Sundram
  • 12,225
  • 19
  • 71
  • 86
Manuel Araoz
  • 15,962
  • 24
  • 71
  • 95
  • Do you need to use pyglet? pygame would make this much easier – John La Rooy Aug 20 '10 at 06:55
  • @gnibbler: Yeah, my code was originally written in pygame and it worked (at least at home). But I needed to run it at my university and I couldn't make virtualenv to support pygame... So I went for pyglet – Manuel Araoz Aug 31 '10 at 05:04

2 Answers2

8

As long as you realize this is going to take a long time...:

pyglet.graphics.draw can drawn one or more points when you pass it pyglet.gl.GL_POINTS, and you can pass attributes such as color as well as coordinates. For example:

for i in range(50):
    for j in range(50):
        color = int(2.56 * (i + j))
        pyglet.graphics.draw(1, pyglet.gl.GL_POINTS,
            ('v2i', (i, j)),
            ('c3B', (color, color, color))
        )

draws a 50 by 50 square with a diagonal gradient from black to white-ish. Just don't expect it to be particularly fast at doing that;-) -- GL is really oriented to graphics with much higher level of abstraction, not "pixel by pixel" painting.

You could get a modicum of extra speed by computing (say) a row at a time, and drawing that, instead of actually drawing pixels singly. But it still won't be super-fast!-)

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
0

You can use an ImageData object and blit it. Here is an example:

import numpy as np
import pyglet


WIDTH = 512
HEIGHT = 512
RGB_CHANNELS = 3
MAX_COLOR = 255


screen = np.zeros(
    [HEIGHT, WIDTH, RGB_CHANNELS], dtype=np.uint8
)
IMG_FORMAT = 'RGB'
pitch = WIDTH * RGB_CHANNELS
window = pyglet.window.Window(WIDTH, HEIGHT)

@window.event
def on_draw():
    window.clear()
    image_data.blit(0, 0)


if __name__ == '__main__':
    image_data = pyglet.image.ImageData(
        WIDTH, HEIGHT, IMG_FORMAT, screen.tobytes(), pitch
    )
    # Use a numpy array to store the pixels
    for j in range(HEIGHT):
        screen[j, :, :] = round((j / HEIGHT) * MAX_COLOR)
    # Flip the up coordinates
    data = np.flipud(screen).tobytes()
    # If your pixels change you can use set_data
    image_data.set_data(IMG_FORMAT, pitch, data)
    pyglet.app.run()
xhenryx14
  • 704
  • 6
  • 10