在Pyglet中设置单个像素

时间:2010-10-18 18:50:46

标签: python pyglet

有没有办法在Pyglet中为图像数据设置单个像素值?

我想也可以通过将OpenGL渲染模式设置为点来完成,所以如果有人对此有所了解,请分享它。

3 个答案:

答案 0 :(得分:4)

最适合我的解决方案是使用每个AbstractImage子类附带的ImageData类。

ImageData数组检索

ImageData类将图像表示为字节数组,或者更准确地说是一个字符串,其中每个字符表示所需颜色空间中的坐标。

要获得给定image的字节表示,您可以调用

image_data = image.get_image_data()
width = image_data.width
data = image_data.get_data('RGB', 3*width)

这里我们传递给get_data的第二个参数是我们期望为图像的每一行获得的字节数。因为我们想要为每个像素提供所有组件R,G和B,所以我们希望拥有图像宽度的3倍。如果我们只对每个像素的强度感兴趣,我们会传递参数('I', image.width)Here's some official documentation

仅为您感兴趣的像素获取值,例如在(x,y)的那个,您可能想要这样做:

pos = (width*y + x) * 3  
rgb = map(ord, data[pos:pos+3])

除了检索整个图像的ImageData并在之后选择所需的像素值之外,您还可以调用get_image_data()获取某个region,即所需位置的1x1像素:

image_data = image.get_region(x,y,1,1).get_image_data()

它的完成方式是this google groups post,您还可以在其中找到有用的信息,将您的图像数据设置为RGBA而不是RGB更高效

设置单个像素

现在,为了最终回答问题,还有一个用于ImageData的图像字节数据的setter方法,set_data,它可以反过来工作。

image_data.set_data('RGB', image.width*3, data)

这也适用于地区,但我没有尝试过。如果要设置存储在整数数组中的字节数据,请传递''.join(map(chr, data))。我不知道是否有办法设定数值。

希望这可以帮助任何人绊倒这个相当古老的问题,而这恰好是某些搜索字词的显着谷歌结果。

答案 1 :(得分:2)

以下纯粹来自OpenGL的观点,我不知道有任何pyglet技巧。

总有glDrawPixels,或者您可以使用与窗口分辨率相同的OpenGL纹理(如果您可以使用两种纹理大小的非幂,则最好)然后将该纹理映射到四边形占据了整个窗口。

后者我认为是最快的解决方案,因为您无需在每次刷新时更改像素,因为所有数据都已在卡上。

您可以保留纹理数据的“本地”(在cpu内存中)缓存,以便于修改和重新上传。或者,对于奖励积分,您可以直接通过OpenCL修改纹理数据;)

答案 2 :(得分:2)

您可以使用batch = pyglet.graphics.Batch()设置批处理,然后通过调用batch.add(npts, gl_type, group, pixel_data, color_data)将顶点添加到批处理中,其中npts是指定您将在pixel_data中列为元组的点数的整数,以及gl_type在你的情况下是pyglet.gl.GL_POINTS。然后batch.draw()会绘制您添加到批处理中的所有顶点。以下示例通过在每次调用on_draw()时向批处理添加顶点(即GL_POINTS)来绘制一条线:

import pyglet

COLOR = (0,255,0)
FRAMERATE = 1.0/60
(x,y) = (50,50)
window = pyglet.window.Window()
batch = pyglet.graphics.Batch()

# the vertex_list will keep a handle on all the vertices we add to the batch
vertex_list = [batch.add(1, pyglet.gl.GL_POINTS, None,('v2i', (x,y)),('c3B', COLOR))]

@window.event
def on_draw():
   window.clear()

   # the next vertex will use the vertices of the vertex currently at the end of the current vertex_list
   (x,y) = vertex_list[-1].vertices 
   vertex_list.append(batch.add(1, pyglet.gl.GL_POINTS, None,('v2i', (x+1,y+1)),('c3B', COLOR)))       
   batch.draw()

pyglet.clock.schedule_interval(lambda dt: None, FRAMERATE) 
pyglet.app.run()

绘制线条的方式可能比上面的方式更有效,但这种方式可以让您更好地了解批处理的工作原理。查看文档了解更多here.