AVDataProcess/rgb24_to_bmp.cpp

100 lines
4.2 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int BOOL;
#define TRUE 1
#define FALSE 0
//位图文件头结构体
//这个结构体的长度是固定的14个字节。
//考虑到结构体的字节对齐将bfType单独提取出来否则会造成该结构体为16个字节。
static unsigned short bfType = 0x4D42;//指定文件类型必须是0x424D
//即字符串“BM”也就是说所有.bmp文件的头两个字节都是“BM”。
//'BM'表示这是Windows支持的位图格式。
typedef struct {
unsigned int bfSize; //指定文件大小以字节为单位包括这14个字节。
unsigned short bfReserved1; //为保留字,不用考虑
unsigned short bfReserved2; //为保留字,不用考虑
unsigned int bfOffBits; //位图文件头到数据的偏移量,以字节为单位
}BmpHead;
//位图信息头结构体
typedef struct {
unsigned int biSize; //该结构大小字节为单位一般为40个字节
unsigned int biWidth; //指定图象的宽度,单位是象素。
unsigned int biHeight; //指定图象的高度,单位是象素。
//注:这个值除了用于描述图像的高度之外,它还有另一个用处,
//就是指明该图像是倒向的位图,还是正向的位图。
//如果该值是一个正数,说明图像是倒向的,如果该值是个负数,则说明图像是正向的。
//大多数的BMP文件都是倒向的位图也就是高度值是一个正数。
unsigned short biPlanes; //为目标设备说明颜色平面数必须为1不用考虑
unsigned short biBitCount; //颜色深度,每个象素所需要的位数
unsigned int biCompression; //位图的压缩类型
unsigned int biSizeImage; //位图的大小,以字节为单位
unsigned int biXPelsPerMeter; //位图水平分辨率,每米像素数
unsigned int biYPelsPerMeter; //位图垂直分辨率,每米像素数
unsigned int biClrUsed; //位图实际使用的颜色表中的颜色数
unsigned int biClrImportant; //位图显示过程中重要的颜色数
}InfoHead;
BOOL rgb24_to_bmp(const char *file, int width, int height)
{
if (file == NULL) {
return FALSE;
}
FILE *fpRgb24 = fopen(file, "rb");
FILE *fpBmp = fopen("./out/output_rgb24_to_bmp.bmp", "wb");
//从文件中读取RGB数据
unsigned char *rgb24Buf = (unsigned char *)malloc(width*height*3);
memset(rgb24Buf, 0, width*height*3);
fread(rgb24Buf, 1, width*height*3, fpRgb24);
int headSize = sizeof(BmpHead) + sizeof(InfoHead) + sizeof(bfType);
BmpHead bmpHead = {0};
InfoHead bmpInfoHead = {0};
bmpHead.bfSize = width*height*3 + headSize;
bmpHead.bfOffBits = headSize;
bmpInfoHead.biSize = sizeof(InfoHead);
bmpInfoHead.biWidth = width;
bmpInfoHead.biHeight = -height;//BMP存储像素数据在Y轴方向从下到上。
bmpInfoHead.biPlanes = 1;
bmpInfoHead.biBitCount = 24;
bmpInfoHead.biSizeImage = width*height*3;
fwrite(&bfType, 1, sizeof(bfType), fpBmp);
fwrite(&bmpHead, 1, sizeof(bmpHead), fpBmp);
fwrite(&bmpInfoHead, 1, sizeof(bmpInfoHead), fpBmp);
//BMP采用的是小端Little Endian存储方式。
//这种存储方式中“RGB24”格式的像素的分量存储的先后顺序为B、G、R。
//由于RGB24格式存储的顺序是R、G、B所以需要将“R”和“B”顺序作一个调换再进行存储。
for (int i=0; i<height; i++) {
for (int j=0; j<width; j++) {
unsigned char tmp = rgb24Buf[(i*width+j)*3+2];
rgb24Buf[(i*width+j)*3+2] = rgb24Buf[(i*width+j)*3+0];
rgb24Buf[(i*width+j)*3+0] = tmp;
}
}
fwrite(rgb24Buf, width*height*3, 1, fpBmp);
free(rgb24Buf);
fclose(fpBmp);
fclose(fpRgb24);
return TRUE;
}
int main(int argc, char *argv[])
{
if (argc == 4) {
rgb24_to_bmp(argv[1], atoi(argv[2]), atoi(argv[3]));
}
return 0;
}