⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rgb-ycrcb.txt

📁 详细说明了各种颜色格式的转换关系
💻 TXT
📖 第 1 页 / 共 3 页
字号:


read(device_fd, tmp, Mywidth*Myheight*3);
for(int i = 0; i < 176 * 144; ++i)
{
  buffer[4*i] = tmp[3*i];//first bit is blue
  buffer[4*i + 1] = tmp[3*i + 1];//second bit is green
  buffer[4*i + 2] = tmp[3*i + 2] ;//third bit is red
  buffer[4*i + 3] = 130;//forth bit
}
//后面这此是用QT库写的,意思是将buffer的内容转为image再转为pixmap,然后显示出来
QImage img(buffer, Mywidth, Myheight, 32, NULL, 0, QImage::LittleEndian); 
QPixmap pic;
pic.convertFromImage(img);
PixmapVideo->setPixmap(pic);

 

FillEllips 函数填充指定的椭圆。椭圆心为(sx, sy),X 轴半径为 rx,Y 轴半径为 ry。 
  FillSector 函数填充由圆弧和两条半径形成的扇形。圆心为(x, y),半径为 r,起始弧度为 ang1,终止弧度为 ang2。 
  FillPolygon 函数填充多边形。pts 表示多边形各个顶点,vertices 表示多边形顶点个数。 
  FloodFill 从指定点(x, y)开始填注。 
  需要注意的是,所有填充函数使用当前画刷属性(颜色),并且受当前光栅操作的影响。
  
  下面的例子说明了如何使用 FillCircle 和 FillEllipse 函数填充圆或者椭圆。假定给定了两个点,pts[0] 和 pts[1],其中 pts[0] 是圆心或者椭圆心,而 pts[1] 是圆或者椭圆外切矩形的一个顶点。
  
        int rx = ABS (pts[1].x - pts[0].x);
        int ry = ABS (pts[1].y - pts[0].y);
  
        if (rx == ry)
          FillCircle (hdc, pts[0].x, pts[0].y, rx);
        else
          FillEllipse (hdc, pts[0].x, pts[0].y, rx, ry);
  
  5 建立复杂区域
  
  除了利用填充生成器进行填充绘制以外,我们还可以使用填充生成器建立由封闭曲线包围的复杂区域。我们知道,MiniGUI 当中的区域是由互不相交的矩形组成的,并且满足 x-y-banned 的分布规则。利用上述的多边形或者封闭曲线生成器,可以将每条扫描线看成是组成区域的高度为 1 的一个矩形,这样,我们可以利用这些生成器建立复杂区域。MiniGUI 利用现有的封闭曲线生成器,实现了如下的复杂区域生成函数:
  
  BOOL GUIAPI InitCircleRegion (PCLIPRGN dst, int x, int y, int r);
  BOOL GUIAPI InitEllipseRegion (PCLIPRGN dst, int x, int y, int rx, int ry);
  BOOL GUIAPI InitPolygonRegion (PCLIPRGN dst, const POINT* pts, int vertices);
  BOOL GUIAPI InitSectorRegion (PCLIPRGN dst, const POINT* pts, int vertices);
  
  利用这些函数,我们可以将某个区域分别初始化为圆、椭圆、多边形和扇形区域。然后,可以利用这些区域进行点击测试(PtInRegion 和 RectInRegion),或者选择到 DC 当中作为剪切域,从而获得特殊显示效果。
  
  6 直接访问显示缓冲区
  
  在新的 GDI 接口中,我们添加了用来直接访问显示缓冲区的函数,原型如下:
  
  Uint8* GUIAPI LockDC (HDC hdc, const RECT* rw_rc, int* width, int* height, int* pitch);
  void GUIAPI UnlockDC (HDC hdc);
  
  LockDC 函数锁定给定 HDC 的指定矩形区域(由矩形 rw_rc指定,设备坐标),然后返回缓冲区头指针。当 width、height、pitch 三个指针不为空时,该函数将返回锁定之后的矩形有效宽度、有效高度和每扫描线所占的字节数。 
  UnlockDC 函数解开已锁定的 HDC。 
  锁定一个 HDC 意味着 MiniGUI 进入以互斥方式访问显示缓冲区的状态。如果被锁定的 HDC 是一个屏幕 DC(即非内存 DC),则该函数将在必要时隐藏鼠标光标,并锁定 HDC 对应的全局剪切域。在锁定一个 HDC 之后,程序可通过该函数返回的指针对锁定区域进行访问。需要注意的是,不能长时间锁定一个 HDC,也不应该在锁定一个 HDC 时进行其他额外的系统调用。
  
  假定以锁定矩形左上角为原点建立坐标系,X 轴水平向右,Y 轴垂直向下,则可以通过如下的公式计算该坐标系中(x, y)点对应的缓冲区地址(假定该函数返回的指针值为 frame_buffer):
  
    Uint8* pixel_add = frame_buffer + y * (*pitch) + x * GetGDCapability (hdc, GDCAP_BPP);
  
  根据该 HDC 的颜色深度,就可以对该象素进行读写操作。作为示例,下面的程序段随机填充锁定区域:
  
    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);
  
  
  7 YUV 覆盖和 Gamma 校正
  
  为了增强 MiniGUI 对多媒体的支持,我们增加了对 YUV 覆盖(Overlay)和 Gamma 校正的支持。
  
  7.1 YUV 覆盖(Overlay)
  
  多媒体领域中,尤其在涉及到 MPEG 播放时,通常使用 YUV 颜色空间来表示颜色,如果要在屏幕上显示一副 MPEG 解压之后的图片,则需要进行 YUV 颜色空间到 RGB 颜色空间的转换。YUV 覆盖最初来自一些显示芯片的加速功能。这种显示芯片能够在硬件基础上完成 YUV 到 RGB 的转换,免去软件转换带来的性能损失。在这种显示芯片上建立了 YUV 覆盖之后,可以直接将 YUV 信息写入缓冲区,硬件能够自动完成 YUV 到 RGB 的转换,从而在 RGB 显示器上显示出来。在不支持 YUV 覆盖的显示芯片上,MiniGUI 也能够通过软件实现 YUV 覆盖,这时,需要调用 DisplayYUVOverlay 函数将 YUV 信息转换并缩放显示在建立 YUV 覆盖的 DC 设备上。
  
  MiniGUI 提供的 YUV 覆盖操作函数原型如下:
  
  /***************************** 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);
  
  有关视频格式的信息,可参见:
  
  http://www.webartz.com/fourcc/indexyuv.htm
  
  有关颜色空间的相互关系的息,可参见:
  
  http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html
  
  7.2 Gamma 校正
  
  Gamma 校正通过为 RGB 颜色空间的每个颜色通道设置 Gamma 因子,来动态调整 RGB 显示器上的实际 RGB 效果。需要注意的是,Gamma 校正需要显示芯片的硬件支持。
  
  应用程序可以通过 SetGamma 函数设置 RGB 三个颜色通道的 Gamma 校正值。该函数原型如下:
  
  int GAL_SetGamma (float red, float green, float blue);
  #define SetGamma GAL_SetGamma
  
  线性 Gamma 校正值的范围在 0.1 到 10.0 之间。如果硬件不支持 Gamma 校正,该函数将返回 -1。
  
  应用程序也可以通过 SetGammaRamp 函数设置 RGB 三个颜色通道的非线性 Gamma 校正值。该函数原型如下:
  
  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
  
  函数 SetGammaRamp 实际设置的是每个颜色通道的 Gamma 转换表,每个表由 256 个值组成,表示设置值和实际值之间的对应关系。当设置屏幕上某个象素的 RGB 分别为 R、G、B 时,实际在显示器上获得的象素 RGB 值分别为:red[R]、green[G]、blue[B]。如果硬件不支持 Gamma 校正,该函数将返回 -1。
  
  函数 GetGammaRamp 获得当前的 Gamma 转换表。
  
  Gamma 校正的最初目的,是为了能够在显示器上精确还原一副图片。Gamma 值在某种程度上表示的是某个颜色通道的对比度变化。但 Gamma 在多媒体和游戏程序中有一些特殊用途――通过 Gamma 校正,可以方便地获得对比度渐进效果。
  
  8 小结
  
  本文描述了自 MiniGUI 1.1.0Pre4 版本发布以来新增的 GDI 接口。这些接口涉及到曲线和填充生成器、复杂曲线的绘制、封闭曲线填充、复杂区域的创建、直接访问 FrameBuffer、YUV 覆盖和 Gamma 校正等等。通过本文的介绍,相信读者能够对 MiniGUI 的新 GDI 接口有一个更加全面的认识。
  


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -