将RGB数据直接保存为图片

 
	当我们要将RGB24格式保存为bmp图片格式时,根据bmp图片格式需要在图片数据之前添加两个结构体
分别为 BITMAPFILEHEADER、BITMAPINFOHEADER
 
<pre name="code" class="cpp"><pre name="code" class="cpp">          BITMAPFILEHEADER bmpFileHeader = {0};
          bmpFileHeader.bfReserved1 = 0;
          bmpFileHeader.bfReserved2 = 0;
          bmpFileHeader.bfType = 0x4D42;
          bmpFileHeader.bfSize = sizeof(bmpFileHeader) + sizeof(BITMAPINFOHEADER) + pic.linesize[0] * frame->height;
          bmpFileHeader.bfOffBits = sizeof(bmpFileHeader) + sizeof(BITMAPINFOHEADER);
          BITMAPINFOHEADER bmiHeader = { 0 };
          bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
          bmiHeader.biWidth = frame->width;
          bmiHeader.biHeight = 0 - frame->height;
          bmiHeader.biPlanes = 1;
<span style="white-space:pre">	</span>// bmp图片位深 
          bmiHeader.biBitCount = 24;
          bmiHeader.biCompression = BI_RGB;
<span style="white-space:pre">		</span>// 像素点数目
          bmiHeader.biSizeImage = pic.linesize[0] * frame->height;
          bmiHeader.biXPelsPerMeter = 0;
          bmiHeader.biYPelsPerMeter = 0;
          bmiHeader.biClrUsed = 0;
          bmiHeader.biClrImportant = 0;
          fwrite( &bmpFileHeader, 1, sizeof(bmpFileHeader), pf );
          fwrite( &bmiHeader, 1, sizeof(bmiHeader), pf );
          fwrite( pic.data[0], 1, pic.linesize[0] * frame->height, pf );
          fclose( pf );




 

 



 int AVFrame_create_bmp(AVFrame *pAVFrame,int width,int height,int bpp = 24)
 {


  //{
   struct SwsContext *img_convert_ctx;
   AVFrame         *pFrameRGB;
   pFrameRGB=avcodec_alloc_frame();
   if(pFrameRGB==NULL)return 0 ;
   int numBytes = avpicture_get_size(PIX_FMT_RGB24, m_pCodecCtx->width,  m_pCodecCtx->height);
   uint8_t * buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
   
   avpicture_fill((AVPicture *)pFrameRGB, buffer, /*PIX_FMT_RGB24*/PIX_FMT_BGR24,m_pCodecCtx->width, m_pCodecCtx->height);
   
   img_convert_ctx = sws_getContext( 
    m_pCodecCtx->width, 
    m_pCodecCtx->height,
    m_pCodecCtx->pix_fmt,
    m_pCodecCtx->width, 
    m_pCodecCtx->height,
    /*PIX_FMT_RGB24*/PIX_FMT_BGR24,//PIX_FMT_YUV420P,
    SWS_BICUBIC, NULL, NULL, NULL);
   
   sws_scale (img_convert_ctx, pAVFrame->data, pAVFrame->linesize,    
    0, m_pCodecCtx->height,
    ((AVPicture *)pFrameRGB)->data, ((AVPicture *)pFrameRGB)->linesize );
   
   sws_freeContext(img_convert_ctx);


   av_free(buffer); 
  //}
 
   DWORD   w =    m_pCodecCtx->width;    
   DWORD   h =    m_pCodecCtx->height;   
   DWORD   BufferLen = WIDTHBYTES(w*24)*h; //当然,如果仔细考虑,还要考虑位图字节对齐;
   BYTE *  pBuffer = new BYTE[BufferLen]; 
   memset(pBuffer,0,BufferLen);


   for(int i =0; i<height; i++)
   {
    //将图像转为bmp存到内存中,这里的图像是倒立的;
    memcpy(pBuffer +(WIDTHBYTES(w*24)*i),pFrameRGB->data[0]+i*pFrameRGB->linesize[0],width*3);
   }  
   
   LPBYTE pbmp = new BYTE[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+BufferLen]; 
   
   BITMAPFILEHEADER bitmapfileheader; memset( &bitmapfileheader, 0, sizeof( BITMAPFILEHEADER ) );     
   bitmapfileheader.bfType = 'MB';    
   bitmapfileheader.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+BufferLen ;   
   bitmapfileheader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);    
   memcpy(pbmp,&bitmapfileheader,sizeof(BITMAPFILEHEADER));    


   BITMAPINFOHEADER fmtFrame; memset(&fmtFrame, 0, sizeof(fmtFrame));     
   fmtFrame.biSize = sizeof(fmtFrame);  
   fmtFrame.biPlanes  = 1;  
   fmtFrame.biBitCount = 24;  
   fmtFrame.biWidth =   w;   
   fmtFrame.biHeight =  -h;//注意,这里的bmpinfo.bmiHeader.biHeight变量的正负决定bmp文件的存储方式,如果为负值,表示像素是倒过来的*/
   fmtFrame.biSizeImage = BufferLen;  
   memcpy(pbmp+sizeof(BITMAPFILEHEADER),&fmtFrame,sizeof(BITMAPINFOHEADER));   
   memcpy(pbmp+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),pBuffer, BufferLen);  
   
   FILE * f = fopen("frame.bmp","w+b");
   fwrite(pbmp,1,sizeof(BITMAPFILEHEADER)+sizeof(fmtFrame)+BufferLen, f );  
   fclose(f) ; 
   
   delete [] pbmp; pbmp = NULL;
   delete [] pBuffer; pBuffer = NULL; 
 }


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值