C语言 128位bmp生成,[转载]生成BMP格式位图,附C++代码

本文详细介绍了如何将USB视频摄像头捕获的RGB24和I420格式数据转换为BMP位图,并提供了生成BMP图像的函数示例。通过实例演示了如何创建一个黑白背景带有矩形的320x240位图,同时提到了BMP格式的特点和可能的压缩方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

USB视频摄像头的媒体格式为RGB24和I420,如何把这些数据变成BMP位图存下来呢?请看本文。

首先,我们了解一下BMP的格式,BMP有四部分组成,用表格表示如下:

1. 文件信息头

2. 位图信息头

3. 调色板

4. 位图数据

第一部分,文件信息头的格式如下:

typedef struct tagBITMAPFILEHEADER {

WORD bfType;

DWORD bfSize;

WORD bfReserved1;

WORD bfReserved2;

DWORD bfOffBits;

} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER,

*PBITMAPFILEHEADER;

共有14个字节,其中bfType为文件类型,BMP的类型为0×4d42,也就是字母m和b;bfSize是文件大小,为1,2,3,4部分大小的总和;bfReserved1和bfReserved2为1,2,3部分大小的总和。

第二部分,位图信息头,定义如下:

typedef struct tagBITMAPINFOHEADER{

DWORD biSize;

LONG biWidth;

LONG biHeight;

WORD biPlanes;

WORD biBitCount;

DWORD biCompression;

DWORD biSizeImage;

LONG

biXPelsPerMeter;

LONG biYPelsPerMeter;

DWORD biClrUsed;

DWORD biClrImportant;

} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER,

*PBITMAPINFOHEADER;

总共40个字节,字段比较多,可以查看MSDN中的说明,对于RGB24的位图,这个结构体一般定义如下:

BITMAPINFOHEADER bih;

bih.biSize = sizeof(BITMAPINFOHEADER);

bih.biWidth = width;

bih.biHeight = height;

bih.biPlanes = 1;

bih.biBitCount = 24;

bih.biCompression = 0;

bih.biSizeImage = size;

bih.biXPelsPerMeter = 0;

bih.biYPelsPerMeter = 0;

bih.biClrUsed = 0;

bih.biClrImportant = 0;

第三部分是调色板信息,定义如下:

typedef struct tagRGBQUAD {

BYTE rgbBlue;

BYTE rgbGreen;

BYTE rgbRed;

BYTE rgbReserved;

} RGBQUAD;

这部分用来表示RGB各色的强度,一般情况我们不把这一部分写到文件中。

第四部分就是真正的数据,比如宽度和高度分别是320和240,这部分数据的长度应该为320*240*3(每个像素点上有3个字节,分别用来表示b,g,r的颜色)。

根据对BMP格式的说明,我们可以轻易的写出一个生成BMP图像的函数,如下所示:

// pData为rgb24数据,width为位图宽度,height为位图高度,filename为位图文件的名字

void Snapshot( BYTE * pData, int width, int height, const char *

filename )

{

int size = width*height*3; // 每个像素点3个字节

// 位图第一部分,文件信息

BITMAPFILEHEADER bfh;

bfh.bfType = 0×4d42; //bm

bfh.bfSize = size // data size

+ sizeof( BITMAPFILEHEADER ) // first section size

+ sizeof( BITMAPINFOHEADER ) // second section size

;

bfh.bfReserved1 = 0; // reserved

bfh.bfReserved2 = 0; // reserved

bfh.bfOffBits = bfh.bfSize - size;

// 位图第二部分,数据信息

BITMAPINFOHEADER bih;

bih.biSize = sizeof(BITMAPINFOHEADER);

bih.biWidth = width;

bih.biHeight = height;

bih.biPlanes = 1;

bih.biBitCount = 24;

bih.biCompression = 0;

bih.biSizeImage = size;

bih.biXPelsPerMeter = 0;

bih.biYPelsPerMeter = 0;

bih.biClrUsed = 0;

bih.biClrImportant = 0;

FILE * fp = fopen( filename, “wb” );

if( !fp ) return;

fwrite( &bfh, 1, sizeof(BITMAPFILEHEADER), fp

);

fwrite( &bih, 1, sizeof(BITMAPINFOHEADER), fp

);

fwrite( pData, 1, size, fp );

fclose( fp );

}

如果要对摄像头采集到的数据进行截图,这里可以直接把数据送给这个函数,就可以生成一张位图了。当然也可以自己生成一段数据,用图片的形式保存下来。下面我将给一个例子,说明怎么生成位图,本例中说明了如何生成一个320*240的图像,黑色的背景,中部有一个100*100的矩形,代码如下:

void GenerateBMP()

{

int i=0, j=0;

struct {

BYTE b;

BYTE g;

BYTE r;

} pRGB[240][320]; // 定义位图数据

memset( pRGB, 0, sizeof(pRGB) ); // 设置背景为黑色

// 在中间画一个100*100的矩形

for( int i=70;i<170;i++ ){

for( int j=110;j<210;j++ ){

pRGB[i][j].r = 0xff;

}

}

// 生成BMP图片

Snapshot( (BYTE *)pRGB, 320, 240, “C:\rgb.bmp” );

}

生成图片如下所示:

上面所说的都是对于RGB24的数据,对于I420,可以先转换成RGB24,然后在生成位图。

BMP的数据量是很大的,没有经过任何的压缩,我们可以计算一下,对于一副320*240的图像,图片的大小是320*240*3 =

230400 bytes = 225

Kbytes,普通电脑一副屏幕截图就要1024*768*3=2.3M。所以我们要用一些流行的算法对图片进行压缩才便于存储,下一篇文章,我将介绍如何把BMP的文件压缩成JPG的文件,压缩比大概在80倍左右,请关注下文。

11-10补充:

感谢张欣网友把上述代码完整的整理出来,经过我的小的改动,C代码如下:

#include “stdio.h”

#include “stdlib.h”

#include “string.h”

typedef long BOOL;

typedef long LONG;

typedef unsigned char BYTE;

typedef unsigned long DWORD;

typedef unsigned short WORD;

#include

typedef struct {

WORD bfType;

DWORD bfSize;

WORD bfReserved1;

WORD bfReserved2;

DWORD bfOffBits;

} BMPFILEHEADER_T;

struct BMPFILEHEADER_S{

WORD bfType;

DWORD bfSize;

WORD bfReserved1;

WORD bfReserved2;

DWORD bfOffBits;

};

typedef struct{

DWORD biSize;

LONG biWidth;

LONG biHeight;

WORD biPlanes;

WORD biBitCount;

DWORD biCompression;

DWORD biSizeImage;

LONG biXPelsPerMeter;

LONG biYPelsPerMeter;

DWORD biClrUsed;

DWORD biClrImportant;

} BMPINFOHEADER_T;

void Snapshot( BYTE * pData, int width, int

height, char * filename )

{

int size = width*height*3; // 每个像素点3个字节

// 位图第一部分,文件信息

BMPFILEHEADER_T bfh;

bfh.bfType = 0×4d42; //bm

bfh.bfSize = size // data size

+ sizeof( BMPFILEHEADER_T ) // first section size

+ sizeof( BMPINFOHEADER_T ) // second section size

;

bfh.bfReserved1 = 0; // reserved

bfh.bfReserved2 = 0; // reserved

bfh.bfOffBits = bfh.bfSize - size;

// 位图第二部分,数据信息

BMPINFOHEADER_T bih;

bih.biSize = sizeof(BMPINFOHEADER_T);

bih.biWidth = width;

bih.biHeight = height;

bih.biPlanes = 1;

bih.biBitCount = 24;

bih.biCompression = 0;

bih.biSizeImage = size;

bih.biXPelsPerMeter = 0;

bih.biYPelsPerMeter = 0;

bih.biClrUsed = 0;

bih.biClrImportant =

0;

FILE * fp = fopen( filename,”wb” );

if( !fp ) return;

fwrite( &bfh, 1, sizeof(BMPFILEHEADER_T), fp );

fwrite( &bih, 1, sizeof(BMPINFOHEADER_T), fp );

fwrite( pData, 1, size, fp );

fclose( fp );

}

void main()

{

int i=0, j=0;

struct {

BYTE b;

BYTE g;

BYTE r;

} pRGB[240][320]; // 定义位图数据

memset( pRGB, 0, sizeof(pRGB) ); // 设置背景为黑色

// 在中间画一个100*100的矩形

for( i=70;i<170;i++ ){

for( j=110;j<210;j++ ){

pRGB[i][j].r = 0xff;

}

}

// 生成BMP图片

Snapshot( ( BYTE*)pRGB, 320, 240, “c:\rgb.bmp” );

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值