如何直接在屏幕上绘制像素?

16

我想要做类似以下的事情:

...
pixel[0,0] = [ 254, 0, 0 ] # Draw R at pixel x0y0
pixel[2,1] = [ 0, 254, 0 ] # Draw G at pixel x2y1
pixel[4,2] = [ 0, 0, 254 ] # Draw B at pixel x4y2
...

我希望在短时间内展示许多不同的像素和颜色配置,将其写入中间文件会太昂贵。

在Python中,我应该如何最好地实现这个目标?


4
通常情况下,你不希望写入“屏幕”,而是希望写入窗口。Python中没有任何内置的用于与窗口交互的包,因此你需要选择并安装一些东西。 - Mark Ransom
@MarkRansom - 对的。一个无边框窗口也是可以接受的。 - Matthieu Cartier
如果您知道如何将内容写入文件,那么您可以使用cStringIO将其写入内存,尽管我认为这不是这种情况。 - heltonbiker
@Mark Ransom:使用tkinter,您可以创建和显示窗口。内置的。 - glglgl
3个回答

28

直接回答:

这只能通过特定于操作系统的API完成。有些操作系统不允许直接更改屏幕上的像素。

在Windows上,您可以使用pywin32库调用dc = GetDC(0)获取屏幕的设备上下文,然后使用SetPixel(dc, x, y, color)来绘制像素。

import win32gui
import win32api

dc = win32gui.GetDC(0)
red = win32api.RGB(255, 0, 0)
win32gui.SetPixel(dc, 0, 0, red)  # draw red at 0,0

当然,你用这种方式绘制的内容可以随时被擦除。

正确答案:

以像素为单位逐个绘制图像是最慢的绘画方式。例如,在Windows平台上,创建一个内存中的图像,然后通过一次操作将其绘制出来比使用SetPixel逐个绘制要快得多。

如果你需要速度,可以使用Python的一些用户界面库,例如Tkinter模块或PyQt。在内存中创建一个窗口和图像,然后将图像绘制在窗口上。如果你需要操作像素,就在图像上进行操作,并在每次操作后重新绘制。


3
你知道如何在Ubuntu上做同样的事情吗? - killajoule
如何撤销使用win32gui.SetPixel绘制的像素? - Amin Guermazi
@Amin:首先使用win32gui.GetPixel(dc, 0, 0)保存像素的值,以便稍后恢复。 - martineau
这个问题已经超过一年了,我甚至不记得当时为什么需要它了。 - Amin Guermazi

4
虽然它并不完全按照你所说的(以“像素”为基础绘制),但我喜欢使用Python、GTK和Cairo。
在这种情况下,您可以创建一个GTK窗口,添加一个DrawingArea,创建一个Cairo上下文,并执行绘图操作。
区别在于您有一个连续的带有浮点坐标的画布,而不是像素,您绘制具有描边和填充的几何形状。您甚至可以绘制一个像素大小的矩形并进行填充,但速度不会那么快。
此外,您可以一次渲染任何栅格对象(图像、pixbuffer)。然后,您可以快速生成一系列图像,并将其像素一次性渲染,类似于电影。
您可以在这里查看一个可行的示例(第二个片段):quickest way to get started with cairo

3

我不确定我是否理解了你的问题,但我相信你应该调查一些框架或中间件,让你可以访问屏幕。我建议使用PyGame、Pyglet甚至是Panda。这可能有点过度,因为Pygame和Panda是让你开发游戏的框架,而Pyglet是Python中Opengl的封装,但它将让你轻松地控制像素、窗口和类似的东西。


2
有些人喜欢尝试各种东西,不在乎是否已经存在一个可以比他们快100倍的库。 - Joel M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接