热门标签 | 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位图像,然后由其他高彩色图像向这个空白图像填充数据的情况。

 

推荐阅读
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 修复安装win10失败并提示“磁盘布局不受UEFI固件支持”的方法
    本文介绍了修复安装win10失败并提示“磁盘布局不受UEFI固件支持”的方法。首先解释了UEFI的概念和作用,然后提供了两种解决方法。第一种方法是在bios界面中将Boot Mode设置为Legacy Support,Boot Priority设置为Legacy First,并关闭UEFI。第二种方法是使用U盘启动盘进入PE系统,运行磁盘分区工具DiskGenius,将硬盘的分区表设置为gpt格式,并留出288MB的内存。最后,通过运行界面输入命令cmd来完成设置。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文详细介绍了MySQL表分区的创建、增加和删除方法,包括查看分区数据量和全库数据量的方法。欢迎大家阅读并给予点评。 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
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社区 版权所有