本文是翻译文章,原文地址:http://labs.trolltech.com/blogs/2009/06/09/night-mode-in-qwebview/
“夜间模式”是导航系统的一个有趣特性,它能在四周光照不足的情况下调整屏幕的显示让用户更方便的看清上面的文字和地图。通过反色的小技巧可以实现类似功能。
感谢QPainter,只要短短的几行代码就能很容易的实现这个功能。我们要做的就是使用正确的。如果以前你觉得组合模式是一个神奇的魔盒,那现在正有机会可以一趟究竟。查看,你会发现在QPainter::CompositionMode_Difference或CompositionMode_Exclusion模式下,通过白色进行组合就能将原来的颜色进行反色。这恰巧就是我们需要的特性
例子代码可以在里找到,对应的子目录是webnightmode(包含了Qt/C++和PyQt版本),这里只是使用了QWebView为例子,显然它也适用于其他Widget(参见)。需要注意的是不是所有的画图引擎/设备都支持QPainter::CompositionMode_Difference,这里强制使用X11里的光栅图形系统。
当然,一个实用的夜间模式系统要比当当作一个反色要复杂的多(大家可以开动头脑风暴去想想有什么好的算法)。整体的亮度和对比度都是需要考量的,这在RGB色度空间可能无法完成,需要转到其它颜色空间的运算,这些东西超出了这个例子的讨论范围。
补充:
所谓组合模式就是将QPainter你新生成的内容和原来设备上已经画好的内容的一个运算,默认是覆盖。
《 C++ GUI Programing with Qt4》这本书的第8章对此有详细介绍。夜间模式里使用以下3行代码
QPainter p(this);
p.setCompositionMode(QPainter::CompositionMode_Difference);
p.fillRect(event->rect(), Qt::white);
CompositionMode_Difference模式指的是一种异或(xor)运算,因为white的颜色是全1,所以和原有图像的运算结果刚好是按位取反的功能,做到了反色效果。
最后留一个练习给勇敢的读者:通过选择(CSS或jQuery)找到一个地图元素,并对它作反色处理。
源码链接