如何将RGB565图像数据在窗口类直接显示出来

时间:2020-12-09 11:01:58
如题,如何通过VC编程把已知内存块(如lpbuffer)的RGB565图像数据直接在窗口中显示出来?请说明实现方法,如:需要用到哪些函数,怎么使用这些函数。是否需要将RGB565转换成RGB24呢,可以不用填充BMP头文件实现吗?

10 个解决方案

#1


有谁做过这方面的代码吗?请多多指教啊。

#2


1)可以直接显示RGB565,当然也可以转成RGB888方式显示;2)不需要BMP文件头
具体步骤大致如下:
1)使用CreateDIBSection创建一个设备无关的位图;其中参数ppvBits就是您可以直接用来绘制的缓冲区
2)在使用CreateDIBSection时注意参数:info.bmiHeader.biBitCount为你要的显示颜色位数、info.bmiHeader.biPlanes最好为1(除非你准备用那些古老的16色)、info.bmiHeader.biCompression为RGB
3)直接就可以在这个Buffer上进行绘制;
4)显示:通过BitBlt或StretchBlt什么方式显示在显示设备上

CreateDIBSection比较麻烦一些,但因为有一个可以直接使用的Buffer,使用上很方便,非常适合那些比较灵活的应用;

#3


增加一些简单说明:
1)一般情况下,考虑移植及设备无关;底层(算法层)所使用的颜色数往往和实际设备并不一致;通常情况下,底层考虑未来扩展我会每个Channel使用16Bits,及每个像素为64位,这样作的最大好处是在处理抗锯齿、渐进色处理、颜色扩展上有很大好处(尤其是抗锯齿)
2)在最终画面输出时再根据显示设备的颜色数进行相应转换就可以了

#4


多谢,tomsoft。我是想通过单片机将摄像头采集的RGB565数据通过串口发送到PC然后PC做一些数据的处理并把画面显示出,所以想学习下是否有个简单的方法进行RGB565数据的直接显示。我去了解一下CreateDIBSection函数先,如果还有不懂的地方请多指教啊,谢谢了!

#5


多谢tomsoft。我是想通单片机将摄像头采集的RGB565数据同过串口发送到PC,然后PC进行一些数据分析并直接把RGB565图像显示出来,所以想找个简单的方法来实现。我想学习一下CreateDIBSection函数的用法,如果后面有不懂的地方还请多指教啊,谢谢了!

#6


因我的图片分辨率不是很高,所以我使用SetPixel函数实现了画图功能,但通过ONPAINT在对话框的静态文本框控件画图时为什么窗口需先被隐藏再拉出来显示时,所绘的图才会显示出来啊??按道理ONPAINT函数应该在对话框建立时就被调用啊,程序运行就应该画图的呀。
我在画图函数前增加UPDATEWINDOW可以使程序运行时就画图,但对话框的控件的显示效果却变了,如静态文本框没有立体效果的边框了,这是怎么回事啊?程序如下:
void CPhotoShowDlg::OnPaint() 
{   

UpdateWindow();

CDC*pDC=GetDlgItem(IDC_STATIC)->GetDC();
for(i=0;i<height;i++)
            for(j=0;j<width;j++)
               {
                 pDC->SetPixel(x,y,GRG(r,g,b));
               }

#7


你这叫‘在对话框上绘图’,原则是先Invalid你要的控件,然后在这个控件上绘图,别的不要管,那句向导产生的CPaintDC被你删除了?

#8


您是不是要下图左下角的效果
如何将RGB565图像数据在窗口类直接显示出来

大致思路如下:
1)创建一个静态文本框,有3D效果的,作为框架窗口;
2)以比这个静态文本框略小的尺寸创建一个用于显示的窗口;如下代码:
RECT FrameRECT;
m_StatueFrame.GetClientRect(&FrameRECT);
FrameRECT.left = FrameRECT.left + 1;
FrameRECT.top = FrameRECT.top + 1;
FrameRECT.right = FrameRECT.right - 1;
FrameRECT.bottom= FrameRECT.bottom - 1;

        m_SpectrumView.Create(NULL, "Play View", WS_CHILD|WS_VISIBLE, FrameRECT,
&m_StatueFrame, 0);
关于LZ的程序说明两点:
1)不要使用SetPixel,效率很低的
2)窗口的更新程序是不是有问题

源码在我的资源中:http://download.csdn.net/detail/tomsoft/610384

#9


多谢指导,我现在是想弄明白程序启动时为什么非得先隐藏窗口再调出,图像才会显示出来,貌似窗口第一次调用ONPAINT()函数,没有把控件更新,或者是控件背景色把我的图片隐藏了?不知如何解决。
tomsoft,你的方法应该会更好,但目前我的水平有限,所以我只是想用简单SETPIXEL函数先测试一下系统是否能正常工作,能否帮我分析一下上面的问题的原因吗?万分感谢.

#10


schlafenhamster,你好!
我没有用用到CPaintDC啊,也没发现那个位置调用了啊,向导会自动增加吗?

#1


有谁做过这方面的代码吗?请多多指教啊。

#2


1)可以直接显示RGB565,当然也可以转成RGB888方式显示;2)不需要BMP文件头
具体步骤大致如下:
1)使用CreateDIBSection创建一个设备无关的位图;其中参数ppvBits就是您可以直接用来绘制的缓冲区
2)在使用CreateDIBSection时注意参数:info.bmiHeader.biBitCount为你要的显示颜色位数、info.bmiHeader.biPlanes最好为1(除非你准备用那些古老的16色)、info.bmiHeader.biCompression为RGB
3)直接就可以在这个Buffer上进行绘制;
4)显示:通过BitBlt或StretchBlt什么方式显示在显示设备上

CreateDIBSection比较麻烦一些,但因为有一个可以直接使用的Buffer,使用上很方便,非常适合那些比较灵活的应用;

#3


增加一些简单说明:
1)一般情况下,考虑移植及设备无关;底层(算法层)所使用的颜色数往往和实际设备并不一致;通常情况下,底层考虑未来扩展我会每个Channel使用16Bits,及每个像素为64位,这样作的最大好处是在处理抗锯齿、渐进色处理、颜色扩展上有很大好处(尤其是抗锯齿)
2)在最终画面输出时再根据显示设备的颜色数进行相应转换就可以了

#4


多谢,tomsoft。我是想通过单片机将摄像头采集的RGB565数据通过串口发送到PC然后PC做一些数据的处理并把画面显示出,所以想学习下是否有个简单的方法进行RGB565数据的直接显示。我去了解一下CreateDIBSection函数先,如果还有不懂的地方请多指教啊,谢谢了!

#5


多谢tomsoft。我是想通单片机将摄像头采集的RGB565数据同过串口发送到PC,然后PC进行一些数据分析并直接把RGB565图像显示出来,所以想找个简单的方法来实现。我想学习一下CreateDIBSection函数的用法,如果后面有不懂的地方还请多指教啊,谢谢了!

#6


因我的图片分辨率不是很高,所以我使用SetPixel函数实现了画图功能,但通过ONPAINT在对话框的静态文本框控件画图时为什么窗口需先被隐藏再拉出来显示时,所绘的图才会显示出来啊??按道理ONPAINT函数应该在对话框建立时就被调用啊,程序运行就应该画图的呀。
我在画图函数前增加UPDATEWINDOW可以使程序运行时就画图,但对话框的控件的显示效果却变了,如静态文本框没有立体效果的边框了,这是怎么回事啊?程序如下:
void CPhotoShowDlg::OnPaint() 
{   

UpdateWindow();

CDC*pDC=GetDlgItem(IDC_STATIC)->GetDC();
for(i=0;i<height;i++)
            for(j=0;j<width;j++)
               {
                 pDC->SetPixel(x,y,GRG(r,g,b));
               }

#7


你这叫‘在对话框上绘图’,原则是先Invalid你要的控件,然后在这个控件上绘图,别的不要管,那句向导产生的CPaintDC被你删除了?

#8


您是不是要下图左下角的效果
如何将RGB565图像数据在窗口类直接显示出来

大致思路如下:
1)创建一个静态文本框,有3D效果的,作为框架窗口;
2)以比这个静态文本框略小的尺寸创建一个用于显示的窗口;如下代码:
RECT FrameRECT;
m_StatueFrame.GetClientRect(&FrameRECT);
FrameRECT.left = FrameRECT.left + 1;
FrameRECT.top = FrameRECT.top + 1;
FrameRECT.right = FrameRECT.right - 1;
FrameRECT.bottom= FrameRECT.bottom - 1;

        m_SpectrumView.Create(NULL, "Play View", WS_CHILD|WS_VISIBLE, FrameRECT,
&m_StatueFrame, 0);
关于LZ的程序说明两点:
1)不要使用SetPixel,效率很低的
2)窗口的更新程序是不是有问题

源码在我的资源中:http://download.csdn.net/detail/tomsoft/610384

#9


多谢指导,我现在是想弄明白程序启动时为什么非得先隐藏窗口再调出,图像才会显示出来,貌似窗口第一次调用ONPAINT()函数,没有把控件更新,或者是控件背景色把我的图片隐藏了?不知如何解决。
tomsoft,你的方法应该会更好,但目前我的水平有限,所以我只是想用简单SETPIXEL函数先测试一下系统是否能正常工作,能否帮我分析一下上面的问题的原因吗?万分感谢.

#10


schlafenhamster,你好!
我没有用用到CPaintDC啊,也没发现那个位置调用了啊,向导会自动增加吗?