纯C++代码实现将像素矩阵保存为bmp图片_像素c++简化代码-程序员宅基地

技术标签: yuv保存为图片  

       用C++代码将像素矩阵保存为图片,这里以读取yuv序列视频帧为例进行分析,假设4:2:0yuv序列有300帧,则首先需要将每一视频帧保存在一个像素矩阵中,然后将每一个矩阵保存为图片,最终会有300个bmp图片。

       纯C++代码如下:

       saveToPicture.cpp

#include<iostream>
#include<string>
using namespace std;

#define FrameSize 176*144  //视频帧大小
#define FrameNum 300       //yuv帧数
#define ET_SIZE 300
char errorText[ET_SIZE];

void errorMsg(const char *msg) {
	printf("error:%s\n", msg);
#ifdef _WIN32
	system("pause");
#endif
	exit(-1);
}

void readSequence(char *fileName, unsigned char **frames) {
	FILE *fp = fopen(fileName, "rb");
	if (fp == NULL) {
		sprintf(errorText, "File %s doesn't exist\n", fileName);
		errorMsg(errorText);
	}

	int uvSize = FrameSize / 2;            //H.264编解码获得的关键帧都是彩色序列,这里主要是提取亮度分量Y。
	unsigned char *buf = (unsigned char *)malloc(sizeof(unsigned char) * uvSize);
	for (int i = 0; i < FrameNum; i++) {
		//read y
		if (fread(frames[i], 1, FrameSize, fp) != FrameSize) {  //每一个keyFrames[i]分配的是 (unsigned char) * FrameSize的大小,所以fread要读的每个数据项的字节数为1,可以表示每个像素点亮度范围0~255
			sprintf(errorText, "Input sequence %s is not enough", fileName);
			errorMsg(errorText);
		}

		//read u,v
		fread(buf, 1, uvSize, fp);
	}
	free(buf);
	fclose(fp);
}

void write_bmpheader(unsigned char *bitmap, int offset, int bytes, int value) {
	int i;
	for (i = 0; i < bytes; i++)
		bitmap[offset + i] = (value >> (i << 3)) & 0xFF;
}

unsigned char *convertToBmp(unsigned char *inputImg, int width, int height, int *ouputSize) {
	/*create a bmp format file*/
	int bitmap_x = (int)ceil((double)width * 3 / 4) * 4;
	unsigned char *bitmap = (unsigned char*)malloc(sizeof(unsigned char)*height*bitmap_x + 54);

	bitmap[0] = 'B';
	bitmap[1] = 'M';
	write_bmpheader(bitmap, 2, 4, height*bitmap_x + 54); //whole file size
	write_bmpheader(bitmap, 0xA, 4, 54); //offset before bitmap raw data
	write_bmpheader(bitmap, 0xE, 4, 40); //length of bitmap info header
	write_bmpheader(bitmap, 0x12, 4, width); //width
	write_bmpheader(bitmap, 0x16, 4, height); //height
	write_bmpheader(bitmap, 0x1A, 2, 1);
	write_bmpheader(bitmap, 0x1C, 2, 24); //bit per pixel
	write_bmpheader(bitmap, 0x1E, 4, 0); //compression
	write_bmpheader(bitmap, 0x22, 4, height*bitmap_x); //size of bitmap raw data
	for (int i = 0x26; i < 0x36; i++)
		bitmap[i] = 0;

	int k = 54;
	for (int i = height - 1; i >= 0; i--) {
		int j;
		for (j = 0; j < width; j++) {
			int index = i*width + j;
			for (int l = 0; l < 3; l++)
				bitmap[k++] = inputImg[index];
		}
		j *= 3;
		while (j < bitmap_x) {
			bitmap[k++] = 0;
			j++;
		}
	}

	*ouputSize = k;
	return bitmap;
}

void saveToBmp(unsigned char *inputImg, int width, int height, char *outputFileName) {
	int size;
	unsigned char *bmp = convertToBmp(inputImg, width, height, &size);
	FILE *fp = fopen(outputFileName, "wb+");
	if (fp == NULL) {
		sprintf(errorText, "Could not open file: %s", outputFileName);
		errorMsg(errorText);
	}
	fwrite(bmp, 1, size, fp);
	fclose(fp);
	free(bmp);
}

int main() {
	int width = 176, height = 144;
	unsigned char **oriFrames;
	oriFrames = (unsigned char**)malloc(sizeof(unsigned char*) * FrameNum);
	for (int i = 0; i < FrameNum; i++) {
		oriFrames[i] = (unsigned char*)malloc(sizeof(unsigned char) * FrameSize);
	}
	readSequence("foreman_qcif_300.yuv", oriFrames);
	
	char imgName[30];
	for (int i = 0; i < FrameNum; i++) {
		sprintf(imgName,"./picture/ReconsFrame%d.bmp", i);
		//矩阵oriFrames[i]可以是任何你想保存为图片的像素矩阵,这里是yuv视频图像每一帧的像素数据
		saveToBmp(oriFrames[i], width, height, imgName);  
	}
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sinat_33718563/article/details/79424981

智能推荐

Java集合容器面试题(2020最新版)_1.8为什么只采用两次扰动-程序员宅基地

文章浏览阅读1k次,点赞2次,收藏7次。Java集合容器面试题(2020最新版)最近看到这篇文章作者写的很不错,总结的到位希望更多的人看到,能够帮到更多的人。原创作者 ThinkWon原文链接:https://thinkwon.blog.csdn.net/article/details/104588551) 序号内容链接地址1..._1.8为什么只采用两次扰动

汽车线控转向系统的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_2022-2026年中国线控转向系统(sbw)行业市场行情监测及未来发展前景研究报告-程序员宅基地

文章浏览阅读511次。本文研究全球与中国市场汽车线控转向系统的发展现状及未来发展趋势,分别从生产和消费的角度分析汽车线控转向系统的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:BoschContinentalSchaefflerNexteer AutomotiveZFBethel Automotive SafetyMandoNSKJTEKTNASN Automotive El_2022-2026年中国线控转向系统(sbw)行业市场行情监测及未来发展前景研究报告

sc9832e camera 不能拍RAW图_camera 不能抓raw图-程序员宅基地

文章浏览阅读905次。初始化的时候最后一定要把mipi clk关掉初始化的时候最后一定要把mipi clk关掉初始化的时候最后一定要把mipi clk关掉sunhz@R720xd:~/sl8541e/vendor/sprd/modules/libcamera$ git log -p sensor/sensor_drv/classic/Galaxycore/gc2033/sensor_gc2033_mipi..._camera 不能抓raw图

cef3 源码包 结构目录探究_cef_100_percent-程序员宅基地

文章浏览阅读1.8w次。要使用cef3,我们第一步就是要下载cef的源码包。地址是:http://opensource.spotify.com/cefbuilds/index.html下载完后,我们才能进行下一步编译。不过很多刚入门的小伙伴不太理解,这个下载的包里都包含那些东西,都是什么意思,今天我们就一起探究学习一下。(我们是在windows下开发,所以这篇文章也只是对windows版本的源码包进行探究)对于源..._cef_100_percent

笔趣阁小说api_笔趣阁api接口-程序员宅基地

文章浏览阅读6.9k次,点赞5次,收藏20次。笔趣阁api小说api,提供小说相关api接口,目前支持笔趣阁(https://m.bqkan.com/)。ip地址:http://49.234.123.245:8082笔趣阁(https://m.bqkan.com/)首页ip+/getHome小说分类ip+/getTypes?url=/sort/1_1/小说内容ip+/getContent?url=/0/790/36873824.html查询ip+/Search?s=2758772450457967865&a_笔趣阁api接口

信驰达车规蓝牙模块RF-BM-2642QB1I赋能汽车T-Box_汽车蓝牙模块如何与tsp服务器绑定-程序员宅基地

文章浏览阅读919次,点赞22次,收藏14次。近年来,随着人们对数据传输需求的增长,传统网络布线的通讯方式逐渐显现出满足不了的局限性,与此同时,各种无线传输技术迅速发展。汽车工业同样需要无线通讯技术,但红外技术、802.11、HomeRF等技术在汽车工业中存在一定的局限性,不太适合应用。在众多无线通讯技术中,蓝牙因其短距离无线网络连接的优势,在各行业都得到广泛应用,在汽车行业更是有着广阔的发展前景。T-Box作为当今互联汽车车载系统中至关重要的组成部分,其主要功能是实现汽车与TSP的互联。T-Box不仅是连接汽车的重要通道,也是用户体验的起始点。_汽车蓝牙模块如何与tsp服务器绑定

随便推点

vagrant安装centos7_vagant中安装centos7-程序员宅基地

文章浏览阅读5.8k次,点赞4次,收藏13次。流程如下:1. 下载安装vitural-box2. 下载vagrant3. 添加box4. 初始化box,初始化系统,启动系统1.下载安装virtural-box地址:https://www.virtualbox.org/如上图示,找到对应的版本下载,我用的是window系统,就下载window。至于安装,没什么好说,选好安装路劲,一直点下一步就行。2.下载安装vagr..._vagant中安装centos7

C++ static、const和static const 以及它们的初始化_c++ static 常量 初始化-程序员宅基地

文章浏览阅读5.9w次,点赞22次,收藏144次。 const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间。 static表示的是静态的。类的静态成员函数、静态成员变量是和类相关的,而不是和类的具体对象相关的。即使没有具体对象,也能调用类的静态成员函数和成员变量。一般类的静态函数几乎就是一个全局函数,只不过它的作用域限于包含它的文件中。 在C++中,static静态成员变量不能在类的内部初始化。在类的内部只是声明,定义必须在类定义体的_c++ static 常量 初始化

分享一些对开发很好帮助的网址_cocoachina 类似网址-程序员宅基地

文章浏览阅读2.4k次。1、http://developer.apple.com/iphone/library这个是官方的代码实例2、www.cocoachina.com这个网站比较适合初期开发者,上面的版主之类的也比较热心,一般的问题都会提供帮助3、http://www.tipb.com/国外的一些文章博客,介绍iphone的特性和开发4、http://www.iphon_cocoachina 类似网址

fileinput 时间_Bootstrap 3 响应式上传图片,时间拾取器和表单认证 Fileinput, Date/Time Pickr, Validator...-程序员宅基地

文章浏览阅读49次。1. Bootstrap 3 响应式上传图片 bootstrap-fileinputUsageStep 1: Load the following assets in your header.If you noticed, you need to load the jquery.min.js and bootstrap.min.css in addition to the fileinput.mi..._$pickr

Java解压zip到指定文件夹_java解压压缩包到指定文件夹-程序员宅基地

文章浏览阅读2.9k次,点赞2次,收藏9次。将zip格式的压缩包解压到指定位置_java解压压缩包到指定文件夹

CodeForces CF1454F Array Partition 题目详解_数组 将一个元素放到开头 最少次数 codeforces-程序员宅基地

文章浏览阅读101次。CodeForces CF1454F Array Partition 题目详解_数组 将一个元素放到开头 最少次数 codeforces

推荐文章

热门文章

相关标签