代码之家  ›  专栏  ›  技术社区  ›  ktdrv

在Pyglet中设置单个像素

  •  1
  • ktdrv  · 技术社区  · 14 年前

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

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

    3 回复  |  直到 14 年前
        1
  •  2
  •   Matt Razza    14 年前

    以下纯粹是从OpenGL的角度来看的,我不知道有什么pyglet技巧可以做到这一点。

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

    我认为后者是最快的解决方案,当你不必每次刷新都改变像素,因为所有的数据已经在卡上。

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

        2
  •  4
  •   J. Katzwinkel    12 年前

    我觉得最适合的解决方法是使用 ImageData 类,随每个 AbstractImage

    图像数据数组检索

    这个 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])
    

    而不是检索 图像数据 对于整个图像,然后选择所需像素的值,也可以调用 get_image_data() region ,即所需位置的1x1像素:

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

    就是这样做的 this google groups post ,您还可以在其中找到有用的信息,以便更有效地获取图像数据 RGBA 而不是 RGB .

    设置单个像素

    set_data ,这正好相反。

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

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

    希望这有助于任何人绊倒在这个相当古老的问题上,这是一个突出的谷歌搜索结果某些搜索词。

        3
  •  2
  •   Fred P    13 年前

    您可以使用 batch = pyglet.graphics.Batch() 然后通过调用 batch.add(npts, gl_type, group, pixel_data, color_data) ,其中npts是一个整数,指定将在像素数据中作为元组列出的点数,在您的示例中,gl_type是pyglet.gl.gl_points。 batch.draw()

    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.