把wx的窗体绘图输出到位图

我想用这种低调的含糊不清的标题也没有什么坏处。

问题很简单,我们要把在wx窗体上绘制的图形保存到一个位图文件中去。

首先看一下wx的绘图机制,所有和绘图相关的操作,都从wx.DC这样一个父类继承。DC即Device Context,文档里对这个类的功能有这样的描述

A wx.DC is a device context onto which graphics and text can be drawn. It is intended to represent a number of output devices in a generic way, so a window can have a device context associated with it, and a printer also has a device context. In this way, the same piece of code may write to a number of different devices, if the device context is used as a parameter.

进而,这样的DC包括子类WindowDC,PrinterDC等等,用于在不同的设备上画图。WindowDC又有两个子类ClientDC和MemoryDC。在窗体上画图,就是在EVT_PAINT事件里,应该使用ClientDC的子类PaintDC。而MemoryDC就是在内存中的位图上绘图。要把窗体上的图形输出到位图文件中去,只要把PaintDC中的绘制的图形数据拷贝到MemoryDC上就可以了。

以下是一个典型的OnPaint方法
[codesyntax lang="python" lines="fancy"]
class CanvasAlpha(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
self.SetBackgroundColour(wx.Color(255, 255, 255))
self.Bind(wx.EVT_PAINT, self.OnPaint)

def OnPaint(self, evt):
dc = wx.PaintDC(self)
gc = wx.GraphicsContext.Create(dc)

## draw …
[/codesyntax]
在拷贝之前,首先创建一个新的位图并且指定他的宽高
bitmap = wx.EmptyBitmap(width, height, -1)
获得memoryDC
memDC = wx.MemoryDC()
指定memoryDC的内存对象
memDC.SelectObject(bitmap)
利用DC中一个非常重要的Blit方法,把PaintDC上的图形轻松地拷贝到MemoryDC上(关于参数的意义请参考wx的文档了)
memDC.Blit(0, 0, width, height, dc, 0, 0)
这还没有完,将memoryDC的内存对象设置为null,即传入一个null对象。这一步相当于flush。
memDC.SelectObject(wx.NullBitmap)
最后,用bitmap的Save方法就可以非常轻松地输出图片了
bitmap.SaveFile(filename, wx.BITMAP_TYPE_JPEG)

这样,在窗口中截图也就实现了。

Yes, it is

我发现samson的blog写法是effective的,于是我决定山寨他。

  1. 我又回南京了,虽然对某些组织我还宣称自己身在外地。这次可以多留一段时间,南京还是非常好的。我家出来这里就是两条河,波光粼粼,现在又是绿色最绿青草更青的季节,凉风徐徐树影婆娑,春光明媚心潮暗涌,让人没法不热爱生活。
  2. 回家之后我吹牛说我妈已经可以从厨房退休了。这两天午饭都是我把我妈关在外面,一人独自在厨房里意气风发挥斥方遒。除了切出了钢笔一样的肉丝而且最后根本咬不动以外,其他都还是一切安好的。可歌可泣的是,再也没有没有糊味从厨房传出来了。
  3. 昨天再超市突然发现地上有个秤,于是迈上我轻盈的步伐piapia地站上去,指针的速度那叫一风驰电掣,它在越过70之后依然没有慢下来的迹象。想知道最后它停在哪了吗,移动用户你就编辑短信去吧。
  4. 除了毕业要做的东西,这两天在看微机原理,看CPU指令系统看内存寻址啥啥的。我要是说自己看不懂是不是太丢人了,那我就说看不太懂吧。好像还不知道考什么,下周找pipitu这样的成功人士求经了。顺便把我北京的公交卡郑重地交给她,里面的钱正好够她从火车站到五道口。嗯,另外20块押金的事情面谈。
  5. 今天终于不能忍了,开始升级ubuntu9.04,现在两岸人民虽然还是血浓于水,但是tw.archive源确实没有以前快了。结果换了一个源,到目前为止快6个小时了,1400个软件包还是没有下载完(刚才变成1700了)。反正现在知道的,xorg1.6了,ati的fglrx驱动是不能用了,compositing没了,但一样可以欣赏朴素的美。
  6. 然后昨天舜天队赢球了,超乎想像异乎寻常,客场两球干净利落地拿下领头羊天津。下周主场对河南我是无论如何要亲临现场了,单身看球,看一场少一场了。
  7. 人生啊。