c++ - 显示 RGB888 内容

标签 c++ c windows-mobile rgb windows-ce

我必须使用 ShowRGBContent 函数显示 RGB888 内容。

下面的函数是yv12->rgb565 & UYVY->RGB565ShowRGBContent函数

static void ShowRGBContent(UINT8 * pImageBuf, INT32 width, INT32 height) 
{
LogEntry(L"%d : In %s Function \r\n",++abhineet,__WFUNCTION__);
UINT16 * temp;
BYTE rValue, gValue, bValue;

// this is to refresh the background desktop
ShowWindow(GetDesktopWindow(),SW_HIDE);
ShowWindow(GetDesktopWindow(),SW_SHOW); 

for(int i=0; i<height; i++)
{
 for (int j=0; j< width; j++)        
 {
  temp = (UINT16 *) (pImageBuf+ i*width*PP_TEST_FRAME_BPP+j*PP_TEST_FRAME_BPP);
  bValue = (BYTE) ((*temp & RGB_COMPONET0_MASK) >> RGB_COMPONET0_OFFSET) << (8 -RGB_COMPONET0_WIDTH);
  gValue = (BYTE) ((*temp & RGB_COMPONET1_MASK) >> RGB_COMPONET1_OFFSET) << (8 -RGB_COMPONET1_WIDTH);
  rValue = (BYTE) ((*temp & RGB_COMPONET2_MASK) >> RGB_COMPONET2_OFFSET) << (8 -RGB_COMPONET2_WIDTH);            
  SetPixel(g_hDisplay, SCREEN_OFFSET_X + j, SCREEN_OFFSET_Y+i, RGB(rValue, gValue, bValue));
 }
}

Sleep(2000); //sleep here to review the result

LogEntry(L"%d :Out %s Function \r\n",++abhineet,__WFUNCTION__);
}

我必须为 RGB888 修改这个

在上面的函数中:

************************
RGB_COMPONET0_WIDTH = 5
RGB_COMPONET1_WIDTH = 6
RGB_COMPONET2_WIDTH = 5
************************

************************
RGB_COMPONET0_MASK = 0x001F //31 in decimal
RGB_COMPONET1_MASK = 0x07E0 //2016 in decimal
RGB_COMPONET2_MASK = 0xF800 //63488 in decimal
************************

************************
RGB_COMPONET0_OFFSET = 0
RGB_COMPONET1_OFFSET = 5
RGB_COMPONET2_OFFSET = 11
************************

************************
SCREEN_OFFSET_X = 100
SCREEN_OFFSET_Y = 0
************************

Here 
Also PP_TEST_FRAME_BPP = 2 for yv12 -> RGB565 & UYVY -> RGB565

iOutputBytesPerFrame = iOutputStride * iOutputHeight; 
// where iOutputStride = (iOutputWidth * PP_TEST_FRAME_BPP) i.e (112 * 2)  
// & iOutputHeight = 160 
// These are in case of RGB565

pOutputFrameVirtAddr = (UINT32 *) AllocPhysMem( iOutputBytesPerFrame, 
                                                PAGE_EXECUTE_READWRITE, 
                                                0,
                                                0,
                                                (ULONG *) &pOutputFramePhysAddr); 

// PAGE_EXECUTE_READWRITE = 0x40 mentioned in winnt.h

// Width =112 & Height = 160 in all the formats for i/p & o/p

现在我的任务是 RGB888。 请指导我在这方面应该做什么。 **提前致谢。

最佳答案

从 yuv444 到 rgb888 的转换非常简单,因为所有组件都位于字节边界上,所以甚至不需要位掩码。根据wikipedia article评论区提到的nobugz,可以通过下面的方式进行定点转换

UINT8* pimg = pImageBuf;
for(int i=0; i<height; i++)
{
    for (int j=0; j< width; j++)        
    {
        INT16 Y = pimg[0];
        INT16 Cb = (INT16)pimg[1] - 128;
        INT16 Cr = (INT16)pimg[2] - 128;
        rValue = Y + Cr + Cr >> 2 + Cr >> 3 + Cr >> 5
        gValue = Y - (Cb >> 2 + Cb >> 4 + Cb >> 5) -
                 (Cr >> 1 + Cr >> 3 + Cr >> 4 + Cr >> 5);
        bValue = Y + Cb + Cb >> 1 + Cb >> 2 + Cb >> 6;
        SetPixel(g_hDisplay, SCREEN_OFFSET_X + j, SCREEN_OFFSET_Y+i, RGB(rValue,
                 gValue, bValue));
        pimg+=3;
    }
}

这假设您的 yuv444 是每个样本 8 位(每个像素 24 位)。转换也可以在 float 中完成,但如果它有效,这应该会更快,因为您的源和目标都是定点。我也不确定是否有必要转换为 int16,但我这样做是为了安全。

请注意,yuv444 中的 444 与 rgb888 中的 888 指的不是同一事物。 444 指的是在使用 TUV 色彩空间时经常发生的子采样。例如,在 YUV420 中,Cb 和 Cr 在两个方向上都减少了两倍。 yuv444 只是意味着所有三个组件都被相同地采样(没有二次采样)。 rgb888 中的 888 指的是每个样本的位数(三种颜色分量各 8 位)。

我还没有实际测试过这段代码,但它至少应该让您知道从哪里开始。

关于c++ - 显示 RGB888 内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2432032/

相关文章:

python - 嵌入式 Python 应用程序中 Py_Finalize 期间的 fatal error

c - 什么是 CLOCKS_PER_SEC?

C++多维数组

javascript - 在 Windows Mobile 设备上编写 JavaScript/Ruby 应用程序的最佳方式是什么?

c++ - 如何在庞大的二进制数据中快速识别 1's(Index) 的连续范围?

c++ - 同一类使用的映射引用类

c++ - SFML 闪烁渲染窗口?

C 链表的添加和删除

c# - 如何在移动设备休眠时继续执行?

c# - 如何从 Windows-mobile 获取 MAC 地址?