FFMPEG开发中的常用功能代码①BMP文件的读取、转正并写入AVFrame的data

1.BMP基本格式(仅24,32位)

BMP格式图像由文件头(BITMAPFILEHEADER)、信息头(BITMAPINFOHEADER)和像素数据(RGB)构成,在文件中依次存放,读/写 BMP文件时也依次操作即可。其中在windows系统下,“windows.h”中已包含此三种结构体。

2.BMP读取代码:

//BMP文件格式固定,读取方式大同小异,读取BMP部分是我直接从不知道哪个哥们的博客COPY的,后面加了转正图片和写入AVFrame
//如果中途要转换YUV420,就不要在这里转正了,网上有个高效的YUV420转正的代码,我这个有点慢
//另外,由于要用FFMPEG操作,内存分配也用的FFMPEG的,可以直接换了
//不要在这里把bmpBuffer释放,但是用完AVFrame数据后,不止要释放AVFrame,还要释放AVFrame->data[0]
AVFrame* readBmp2FrameMap(const char*bmpPath,int num)
{

	//二进制读方式打开指定的图像文件  
	FILE *fp=fopen(bmpPath,"rb");  
	if(fp==0) return 0;  
	
	//跳过位图文件头结构BITMAPFILEHEADER  
	fseek(fp, sizeof(BITMAPFILEHEADER),0);  
	//定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中  
	BITMAPINFOHEADER head;     
	fread(&head, sizeof(BITMAPINFOHEADER), 1,fp);    
	//获取图像宽、高、每像素所占位数等信息  
	int biWidth = head.biWidth;  
	int biHeight = head.biHeight;  
	int biBitCount = head.biBitCount;  
	//定义变量,计算图像每行像素所占的字节数(必须是4的倍数)  
	int lineByte=(biWidth * biBitCount/8+3)/4*4;  
	//位图深度
	if(biBitCount != 24 && biBitCount != 32)
	{
		printf("bmp file: %s  is not  24 or 32 bit\n ", bmpPath);
		return 0;
	}
	//申请位图数据所需要的空间,读位图数据进内存  
	uint8_t* bmpBuffer = (uint8_t* )av_malloc(lineByte* biHeight);
	QTime time_;
	time_.start();
	fread(bmpBuffer,1,lineByte * biHeight,fp);  
	//关闭文件  
	fclose(fp);  
	std::cout<<"read time: "<<time_.elapsed()<<"\n";
	//倒置(转正)
	uint8_t* tempData = (uint8_t*)av_malloc(lineByte*biHeight);
	for(int h=0; h<biHeight; h++)
	{
		memcpy(tempData+(biHeight-1-h)*lineByte, bmpBuffer+(h*lineByte), lineByte);
	}
	memcpy(bmpBuffer,tempData,lineByte*biHeight);
	av_free(tempData);
	//
	AVFrame* rgbFrame = av_frame_alloc();
	AVPixelFormat pixFmt ;
	if(biBitCount == 24)
		pixFmt = AV_PIX_FMT_RGB24;
	else if(biBitCount == 32)
		pixFmt = AV_PIX_FMT_RGB32;
	avpicture_fill((AVPicture *)rgbFrame, bmpBuffer,pixFmt, biWidth, biHeight);  
	rgbFrame->width = biWidth;
	rgbFrame->height = biHeight;
	rgbFrame->linesize[0] = lineByte;
	rgbFrame->format = pixFmt;
	return rgbFrame;
}




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值