热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

我解码H264的数据后得到rgb565的数据,保存一帧、一帧的位图成功。但是贴图就失败,贴出来全是黑快。求高人指点下?下面贴代码!

网上找的代码rgb2bmp.h文件#include<stdio.h>typedefunsignedcharBYTE;typedefunsig

//网上找的代码
//rgb2bmp.h文件  

#include   

typedef unsigned char  BYTE;  

typedef unsigned short WORD;  

// BMP图像各部分说明如下  

/***********  

    第一部分    位图文件头  

该结构的长度是固定的,为14个字节,各个域的依次如下:  

    2byte   :文件类型,必须是0x4d42,即字符串"BM"。  

    4byte   :整个文件大小  

    4byte   :保留字,为0  

    4byte   :从文件头到实际的位图图像数据的偏移字节数。  

*************/ 

typedef struct 

{    long imageSize;  

    long blank;  

    long startPosition;  

}BmpHead;  

/*********************  

/*********************  

第二部分    位图信息头  

该结构的长度也是固定的,为40个字节,各个域的依次说明如下:  

    4byte   :本结构的长度,值为40  

    4byte   :图像的宽度是多少象素。  

    4byte   :图像的高度是多少象素。  

    2Byte   :必须是1。  

    2Byte   :表示颜色时用到的位数,常用的值为1(黑白二色图)、4(16色图)、8(256色图)、24(真彩色图)。  

    4byte   :指定位图是否压缩,有效值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS。Windows位图可采用RLE4和RLE8的压缩格式,BI_RGB表示不压缩。  

    4byte   :指定实际的位图图像数据占用的字节数,可用以下的公式计算出来:  

     图像数据 = Width' * Height * 表示每个象素颜色占用的byte数(即颜色位数/8,24bit图为3,256色为1)  

     要注意的是:上述公式中的biWidth'必须是4的整数倍(不是biWidth,而是大于或等于biWidth的最小4的整数倍)。  

     如果biCompression为BI_RGB,则该项可能为0。  

    4byte   :目标设备的水平分辨率。  

    4byte   :目标设备的垂直分辨率。  

    4byte   :本图像实际用到的颜色数,如果该值为0,则用到的颜色数为2的(颜色位数)次幂,如颜色位数为8,2^8=256,即256色的位图  

    4byte   :指定本图像中重要的颜色数,如果该值为0,则认为所有的颜色都是重要的。  

***********************************/ 

typedef struct 
{  

    long    Length;  

    long    width;  

    long    height;  

    WORD    colorPlane;  

    WORD    bitColor;  

    long    zipFormat;  

    long    realSize;  

    long    xPels;  

    long    yPels;  

    long    colorUse;  

    long    colorImportant;  

}InfoHead;  

/***************************  

/***************************  

    第三部分    调色盘结构  颜色表  

    对于256色BMP位图,颜色位数为8,需要2^8 = 256个调色盘;  

    对于24bitBMP位图,各象素RGB值直接保存在图像数据区,不需要调色盘,不存在调色盘区  

    rgbBlue:   该颜色的蓝色分量。  

    rgbGreen:  该颜色的绿色分量。  

    rgbRed:    该颜色的红色分量。  

    rgbReserved:保留值。  

************************/ 

typedef struct 

{         BYTE   rgbBlue;  

         BYTE   rgbGreen;  

         BYTE   rgbRed;  

         BYTE   rgbReserved;  

      /*   void show(void)  

         {  

            printf("Mix Plate B,G,R:%d %d %dn",rgbBlue,rgbGreen,rgbRed);  

         }*/ 

}RGBMixPlate;  

/****************************  

      RGB加上头部信息转换成BMP  

      参数說明:  

      rgb_buffer        :RGB数据文件中的信息  

      nData             :RGB数据的长度  

      nWidth            :图像宽度的像素数  

      nHeight           :图像高度的像素数  

      fp1               :所存放的文件  

*****************************/ 

int RGB2BMP(char *rgb_buffer,int nWidth,int nHeight,FILE*fp1)  

{  

     BmpHead m_BMPHeader;          

     char bfType[2]={'B','M'};  

     m_BMPHeader.imageSize=3*nWidth*nHeight+54;  

     m_BMPHeader.blank=0;  

     m_BMPHeader.startPosition=54;  

    

     fwrite(bfType,1,sizeof(bfType),fp1);  

     fwrite(&m_BMPHeader.imageSize,1,sizeof(m_BMPHeader.imageSize),fp1);  

     fwrite(&m_BMPHeader.blank,1,sizeof(m_BMPHeader.blank),fp1);  

     fwrite(&m_BMPHeader.startPosition,1,sizeof(m_BMPHeader.startPosition),fp1);  

           

     InfoHead  m_BMPInfoHeader;  

     m_BMPInfoHeader.Length=40;   

     m_BMPInfoHeader.width=nWidth;  

     m_BMPInfoHeader.height=nHeight;  

     m_BMPInfoHeader.colorPlane=1;  

     m_BMPInfoHeader.bitColor=24;  

     m_BMPInfoHeader.zipFormat=0;  

     m_BMPInfoHeader.realSize=3*nWidth*nHeight;  

     m_BMPInfoHeader.xPels=0;  

     m_BMPInfoHeader.yPels=0;  

     m_BMPInfoHeader.colorUse=0;  

     m_BMPInfoHeader.colorImportant=0;  

    

     fwrite(&m_BMPInfoHeader.Length,1,sizeof(m_BMPInfoHeader.Length),fp1);  

     fwrite(&m_BMPInfoHeader.width,1,sizeof(m_BMPInfoHeader.width),fp1);  

     fwrite(&m_BMPInfoHeader.height,1,sizeof(m_BMPInfoHeader.height),fp1);  

     fwrite(&m_BMPInfoHeader.colorPlane,1,sizeof(m_BMPInfoHeader.colorPlane),fp1);  

     fwrite(&m_BMPInfoHeader.bitColor,1,sizeof(m_BMPInfoHeader.bitColor),fp1);  

     fwrite(&m_BMPInfoHeader.zipFormat,1,sizeof(m_BMPInfoHeader.zipFormat),fp1);  

     fwrite(&m_BMPInfoHeader.realSize,1,sizeof(m_BMPInfoHeader.realSize),fp1);  

     fwrite(&m_BMPInfoHeader.xPels,1,sizeof(m_BMPInfoHeader.xPels),fp1);  

     fwrite(&m_BMPInfoHeader.yPels,1,sizeof(m_BMPInfoHeader.yPels),fp1);  

     fwrite(&m_BMPInfoHeader.colorUse,1,sizeof(m_BMPInfoHeader.colorUse),fp1);  

     fwrite(&m_BMPInfoHeader.colorImportant,1,sizeof(m_BMPInfoHeader.colorImportant),fp1);  

     fwrite(rgb_buffer,3*nWidth*nHeight,1,fp1);  

     return 0;  

}

pPic 是解码后的BUF,  

void CHttpLinkDlg::showTest(char *pPic)
{
unsigned short* rgb_buffer =(unsigned short*)pPic;
int nWidth = m_width;
int nHeight = m_height;
long total = nWidth*nHeight*3;  

long nData = nWidth*nHeight;
    unsigned char* pVisit =(unsigned char*)malloc(total*sizeof(char));  

    unsigned char* tmp = pVisit;  

    long i =0;  

    unsigned char R,G,B;  

    while(i
    {  

R = *rgb_buffer&0x1f;  

G = (*rgb_buffer>>5)&0x3f;  

B = (*rgb_buffer>>11)&0x1f;  

B = B<<3;  

G = G<<2;  

R = R<<3;  

*pVisit=R;pVisit++;  

*pVisit=G;pVisit++;  

*pVisit=B;pVisit++;  

rgb_buffer++;  

i++;    
}  
/***********  write file *******************/ 
char newFile[50];
static int a445 = 0;
sprintf(newFile, "B_%04d.bmp", a445++);

    FILE *result = fopen(newFile,"wb");  

    if (result == NULL)  

    {  
return ;  
    }  
    RGB2BMP((char *)tmp,nWidth,nHeight,pPic);

    fclose(result);
//  显示
//  //PlayVideo((char *)tmp,nWidth,nHeight);
 // HBITMAP hBmp = (HBITMAP)LoadImage( NULL ,newFile, IMAGE_BITMAP , 0 , 0 , LR_CREATEDIBSECTION | LR_LOADFROMFILE);
//  if (hBmp != NULL){
//  HDC hdc = ::GetDC(m_PlayWind.m_hWnd);
//  HDC mdc = CreateCompatibleDC(hdc);
//  HBITMAP hbmOld = (HBITMAP)::SelectObject(mdc,hBmp);
//  BitBlt(hdc,0,0,nWidth,nHeight,mdc, 0, 0, SRCCOPY);
//  //::SelectObject(mdc, hbmOld);
//  ::DeleteDC(mdc);
//  //delete [] bufRGBA;
//  ::ReleaseDC(m_PlayWind.m_hWnd, hdc);
//  }
}

这里保存图片正常,都保存成功了!下面是我贴图的代码,rgb_buffer解码后的buf和上面的showTest(char *pPic)函数里面处理过后的BUF都试过。
int CHttpLinkDlg::PlayVideo(char *rgb_buffer,int nWidth,int nHeight)
{
BITMAPINFO info;
    memset(&info.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
    info.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
info.bmiHeader.biWidth = nWidth;
info.bmiHeader.biHeight = nHeight;
info.bmiHeader.biPlanes = 1; 
info.bmiHeader.biBitCount = 16; 
info.bmiHeader.biCompression = BI_BITFIELDS;
//  info.bmiColors[0] = (BYTE)0xF800;
//  info.bmiColors[1] = (BYTE)0x07E0;
//  info.bmiColors[2] = (BYTE)0x001F;
HBITMAP hBitmap= CreateDIBSection(NULL, (BITMAPINFO*)&info, DIB_RGB_COLORS, (void**)&rgb_buffer, 0, 0);
if (hBitmap == NULL)
return -1;
HDC hdc = ::GetDC(m_PlayWind.m_hWnd);
HDC mdc = CreateCompatibleDC(hdc);
HBITMAP hbmOld = (HBITMAP)::SelectObject(mdc,hBitmap);
BitBlt(hdc,0,0,nWidth,nHeight,mdc, 0, 0, SRCCOPY);
::SelectObject(mdc, hbmOld);
::DeleteDC(mdc);
::ReleaseDC(m_PlayWind.m_hWnd, hdc);
return 0;
}

出来后黑屏。是在没法子了,求高手指点! 解码后的图片也不太正常,但有数据:

2 个解决方案

#1


?你应该用SetDIBitsToDevice

#2


如果要显示不同格式的16位的图像数据,其实也很简单,有两中方法,第一,是修改CreateDIBSection函数的一个参数类型pBitmapInfo ,把这个默认参数BITMAPINFO修改为BITMAPV4HEADER,这个结构是比较新的BMP信息头,我们稍微修改他的一些成员结构,即修改为如下形式:

 Private Type BITMAPV4HEADER
    Size                As Long
    Width               As Long
    Height              As Long
    Planes              As Integer
    BitCount            As Integer
    Compression         As Long
    SizeImage           As Long
    XPelsPerMeter       As Long
    YPelsPerMeter       As Long
    ClrUsed             As Long
    ClrImportant        As Long
    RedMask             As Long
    GreenMask           As Long
    BlueMask            As Long
    AlphaMask           As Long
End Type

和BITMAPINFO结构相比,他只是多了几个蒙版成员,如果我们实现知道了我们要创建的16位图像的格式,则填充入对应的mask数据,然后在创建DIBSection,显示的时候直接调用Bitblt函数就可以。

第二种方法依旧是在创建DIBSection时,使用修改后的结构体参数,但不填充mask内容,在显示的时候在修改mask,然后调用SetDIBitsToDevice 函数来显示他,当然也要修改SetDIBitsToDevice 的对应的那个参数声明,这种方法实用于先创建一个空白的16位图像,然后由其他高彩色图像向这个空白图像填充数据的情况。

 

推荐阅读
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
author-avatar
手机用户2502858307
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有