📄 基于 linux 和 minigui 的嵌入式系统软件开发指南(七).htm
字号:
<P><A id=6 name=6><SPAN class=atitle2>6 直接访问显示缓冲区</SPAN></A></P>
<P>在新的 GDI 接口中,我们添加了用来直接访问显示缓冲区的函数,原型如下:</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>Uint8* GUIAPI LockDC (HDC hdc, const RECT* rw_rc, int* width, int* height, int* pitch);
void GUIAPI UnlockDC (HDC hdc);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<UL class=noindent>
<LI>LockDC 函数锁定给定 HDC 的指定矩形区域(由矩形 rw_rc指定,设备坐标),然后返回缓冲区头指针。当
width、height、pitch 三个指针不为空时,该函数将返回锁定之后的矩形有效宽度、有效高度和每扫描线所占的字节数。
<LI>UnlockDC 函数解开已锁定的 HDC。 </LI></UL>
<P>锁定一个 HDC 意味着 MiniGUI 进入以互斥方式访问显示缓冲区的状态。如果被锁定的 HDC 是一个屏幕 DC(即非内存
DC),则该函数将在必要时隐藏鼠标光标,并锁定 HDC 对应的全局剪切域。在锁定一个 HDC
之后,程序可通过该函数返回的指针对锁定区域进行访问。需要注意的是,不能长时间锁定一个 HDC,也不应该在锁定一个 HDC
时进行其他额外的系统调用。</P>
<P>假定以锁定矩形左上角为原点建立坐标系,X 轴水平向右,Y 轴垂直向下,则可以通过如下的公式计算该坐标系中(x,
y)点对应的缓冲区地址(假定该函数返回的指针值为 frame_buffer):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE> Uint8* pixel_add = frame_buffer + y * (*pitch) + x * GetGDCapability (hdc, GDCAP_BPP);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>根据该 HDC 的颜色深度,就可以对该象素进行读写操作。作为示例,下面的程序段随机填充锁定区域:</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE> int i, width, height, pitch;
RECT rc = {0, 0, 200, 200};
int bpp = GetGDCapability (hdc, GDCAP_BPP);
Uint8* frame_buffer = LockDC (hdc, &rc, &width, &height, &pitch);
Uint8* row = frame_buffer;
for (i = 0; i < *height; i++) {
memset (row, rand ()%0x100, *width * bpp);
row += *pitch;
}
UnlockDC (hdc);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P><A id=7 name=7><SPAN class=atitle2>7 YUV 覆盖和 Gamma 校正</SPAN></A></P>
<P>为了增强 MiniGUI 对多媒体的支持,我们增加了对 YUV 覆盖(Overlay)和 Gamma 校正的支持。</P>
<P><A id=71 name=71><SPAN class=atitle3>7.1 YUV 覆盖(Overlay)</SPAN></A></P>
<P>多媒体领域中,尤其在涉及到 MPEG 播放时,通常使用 YUV 颜色空间来表示颜色,如果要在屏幕上显示一副 MPEG
解压之后的图片,则需要进行 YUV 颜色空间到 RGB 颜色空间的转换。YUV 覆盖最初来自一些显示芯片的加速功能。这种显示芯片能够在硬件基础上完成
YUV 到 RGB 的转换,免去软件转换带来的性能损失。在这种显示芯片上建立了 YUV 覆盖之后,可以直接将 YUV
信息写入缓冲区,硬件能够自动完成 YUV 到 RGB 的转换,从而在 RGB 显示器上显示出来。在不支持 YUV 覆盖的显示芯片上,MiniGUI
也能够通过软件实现 YUV 覆盖,这时,需要调用 DisplayYUVOverlay 函数将 YUV 信息转换并缩放显示在建立 YUV 覆盖的 DC
设备上。</P>
<P>MiniGUI 提供的 YUV 覆盖操作函数原型如下:</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>/***************************** YUV overlay support ***************************/
/* 最常见的视频覆盖格式.
*/
#define GAL_YV12_OVERLAY 0x32315659 /* Planar mode: Y + V + U (3 planes) */
#define GAL_IYUV_OVERLAY 0x56555949 /* Planar mode: Y + U + V (3 planes) */
#define GAL_YUY2_OVERLAY 0x32595559 /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
#define GAL_UYVY_OVERLAY 0x59565955 /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
#define GAL_YVYU_OVERLAY 0x55595659 /* Packed mode: Y0+V0+Y1+U0 (1 plane) */
/* 该函数创建一个视频输出覆盖
*/
GAL_Overlay* GUIAPI CreateYUVOverlay (int width, int height,
Uint32 format, HDC hdc);
/* 锁定覆盖进行直接的缓冲区读写,结束后解锁 */
int GAL_LockYUVOverlay (GAL_Overlay *overlay);
void GAL_UnlockYUVOverlay (GAL_Overlay *overlay);
#define LockYUVOverlay GAL_LockYUVOverlay
#define UnlockYUVOverlay GAL_UnlockYUVOverlay
/* 释放视频覆盖 */
void GAL_FreeYUVOverlay (GAL_Overlay *overlay);
#define FreeYUVOverlay GAL_FreeYUVOverlay
/* 将视频覆盖传送到指定 DC 设备上。该函数能够进行 2 维缩放
*/
void GUIAPI DisplayYUVOverlay (GAL_Overlay* overlay, const RECT* dstrect);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>有关视频格式的信息,可参见:</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>http://www.webartz.com/fourcc/indexyuv.htm
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>有关颜色空间的相互关系的息,可参见:</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P><A id=72 name=72><SPAN class=atitle3>7.2 Gamma 校正</SPAN></A></P>
<P>Gamma 校正通过为 RGB 颜色空间的每个颜色通道设置 Gamma 因子,来动态调整 RGB 显示器上的实际 RGB
效果。需要注意的是,Gamma 校正需要显示芯片的硬件支持。</P>
<P>应用程序可以通过 SetGamma 函数设置 RGB 三个颜色通道的 Gamma 校正值。该函数原型如下:</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>int GAL_SetGamma (float red, float green, float blue);
#define SetGamma GAL_SetGamma
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>线性 Gamma 校正值的范围在 0.1 到 10.0 之间。如果硬件不支持 Gamma 校正,该函数将返回 -1。</P>
<P>应用程序也可以通过 SetGammaRamp 函数设置 RGB 三个颜色通道的非线性 Gamma 校正值。该函数原型如下:</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>int GAL_SetGammaRamp (Uint16 *red, Uint16 *green, Uint16 *blue);
#define SetGammaRamp GAL_SetGammaRamp
int GAL_GetGammaRamp (Uint16 *red, Uint16 *green, Uint16 *blue);
#define GetGammaRamp GAL_GetGammaRamp
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>函数 SetGammaRamp 实际设置的是每个颜色通道的 Gamma 转换表,每个表由 256
个值组成,表示设置值和实际值之间的对应关系。当设置屏幕上某个象素的 RGB 分别为 R、G、B 时,实际在显示器上获得的象素 RGB
值分别为:red[R]、green[G]、blue[B]。如果硬件不支持 Gamma 校正,该函数将返回 -1。</P>
<P>函数 GetGammaRamp 获得当前的 Gamma 转换表。</P>
<P>Gamma 校正的最初目的,是为了能够在显示器上精确还原一副图片。Gamma 值在某种程度上表示的是某个颜色通道的对比度变化。但 Gamma
在多媒体和游戏程序中有一些特殊用途――通过 Gamma 校正,可以方便地获得对比度渐进效果。</P>
<P><A id=8 name=8><SPAN class=atitle2>8 小结</SPAN></A></P>
<P>本文描述了自 MiniGUI 1.1.0Pre4 版本发布以来新增的 GDI
接口。这些接口涉及到曲线和填充生成器、复杂曲线的绘制、封闭曲线填充、复杂区域的创建、直接访问 FrameBuffer、YUV 覆盖和 Gamma
校正等等。通过本文的介绍,相信读者能够对 MiniGUI 的新 GDI 接口有一个更加全面的认识。</P>
<P><A id=author1 name=author1><SPAN
class=atitle2>作者</SPAN></A><BR>魏永明(ymwei@minigui.org),男,28 岁。1998
年毕业于清华大学精密仪器系,获工学硕士学位。国内最有影响的自由软件项目之一--MiniGUI 的创始人及主要开发人员。著有《Linux
实用教程》与《学用 Linux 与 Windows NT》,并主持翻译了《Red Hat Linux 奥秘》、《Linux 编程宝典》 等大量优秀的
Linux 技术著作。是清华大学 AKA 信息技术协会 Linux
编程技术系列讲座的主讲人。<BR><!-- END PAPER BODY --></P></TD>
<TD width=10><IMG height=1 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(七).files/c.gif" width=10
border=0></TD></TR></TBODY></TABLE><BR clear=all><IMG height=10 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(七).files/c.gif" width=100 border=0><BR>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD align=right width="100%"><A
href="http://www-900.ibm.com/developerWorks/cn/linux/embed/minigui/guide/part7/index.shtml#top">到页首</A></TD>
<TD width=5><IMG height=1 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(七).files/c.gif" width=5
border=0></TD></TR>
<TR vAlign=top>
<TD bgColor=#000000 colSpan=2><IMG height=1 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(七).files/c.gif" width=100
border=0></TD></TR>
<TR vAlign=top>
<TD bgColor=#ffffff colSpan=2><IMG height=8 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(七).files/c.gif" width=100
border=0></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=10 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD>
<FORM action=/developerWorks/cn/cnratings.nsf/RateArticle?CreateDocument
method=post><INPUT type=hidden value="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南"
name=ArticleTitle> <INPUT type=hidden value=linux name=Zone> <INPUT
type=hidden value=/developerWorks/cn/thankyou/feedback-linux.html
name=RedirectURL> <A id=rating name=rating><B>您对这篇文章的看法如何?</B></A>
<TABLE cellSpacing=0 cellPadding=0 width=600 border=0>
<TBODY>
<TR>
<TD colSpan=5><IMG height=8 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(七).files/c.gif" width=100
border=0></TD></TR>
<TR vAlign=top>
<TD width="16%"><INPUT type=radio value=5 name=Rating>真棒!(5)</TD>
<TD width="20%"><INPUT type=radio value=4 name=Rating>好材料 (4)</TD>
<TD width="24%"><INPUT type=radio value=3 name=Rating>一般;尚可 (3)</TD>
<TD width="22%"><INPUT type=radio value=2 name=Rating>需提高 (2)</TD>
<TD width="18%"><INPUT type=radio value=1 name=Rating>太差!
(1)</TD></TR></TBODY></TABLE><BR><B>建议?</B><BR><TEXTAREA name=Comments rows=5 wrap=virtual cols=60></TEXTAREA><BR><BR><INPUT type=submit value=提交反馈意见></FORM></TD></TR>
<TR vAlign=top>
<TD bgColor=#ffffff><IMG height=8 alt=""
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(七).files/c.gif" width=100
border=0></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD align=right>(c) Copyright IBM Corp. 2001, (c) Copyright IBM China
2001, All Right Reserved</TD></TR>
<TR vAlign=top>
<TD class=bbg height=21> <A class=mainlink
href="http://www-900.ibm.com/developerWorks/cn/cgi-bin/click.cgi?url=www-900.ibm.com/cn/ibm/index.shtml&origin=dwhead">关于
IBM</A><SPAN class=divider> | </SPAN><A
class=mainlink
href="http://www-900.ibm.com/developerWorks/cn/cgi-bin/click.cgi?url=www-900.ibm.com/cn/ibm/privacy/index.shtml&origin=dwhead">隐私条约</A><SPAN
class=divider> | </SPAN><A class=mainlink
href="http://www-900.ibm.com/developerWorks/cn/cgi-bin/click.cgi?url=www-900.ibm.com/cn/ibm/legal/index.shtml&origin=dwhead">使用条款</A><SPAN
class=divider> | </SPAN><A class=mainlink
href="http://www-900.ibm.com/developerWorks/cn/cgi-bin/click.cgi?url=www-900.ibm.com/cn/ibm/contact/index.shtml&origin=dwhead">联系
IBM</A></TD></TR></TBODY></TABLE>
<SCRIPT language=JavaScript1.2
src="基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(七).files/stats.js"
type=text/javascript></SCRIPT>
<NOSCRIPT><IMG height=1 alt=""
src="D:\新建文件夹\基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南(七).files\c(1).gif" width=1
border=0></NOSCRIPT> </A></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -