...将这个数组数据作为BMP位图的数据,怎么弄?有程序吗?
发布网友
发布时间:2024-10-08 01:43
我来回答
共1个回答
热心网友
时间:2024-10-08 02:03
你需要了解BMP位图的文件格式:具体参阅百度百科: bmp 这个词条和MSDN。
我写了一个简单的创建24位BMP位图的小程序。 简单演示了bmp位图的格式。
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#define BMP_W 640L
#define BMP_H 480L
void SetBmpInfoHeader(PBITMAPINFOHEADER pbmpih)
{
/* 14~17: 本结构体所占字节数, 固定值40 */
pbmpih->biSize = 40;
/* 18~21: 位图的宽度(以像素pixel为单位) */
pbmpih->biWidth = BMP_W;
/* 22~25: 位图的高度 */
pbmpih->biHeight = BMP_H;
/* 26~27: 目标设备的级别, 固定值:1 */
pbmpih->biPlanes = 1;
/* 28~29: 一个像素所占bit数, 可以是:1(双色)、4(16色)、8(256色)
、16(65536色)、24(真彩色2^24种颜色)、32(真彩色2^32种颜色),具体参阅MSDN。
对于24位真彩色位图, 一个像素占用三个字节,即24 bits */
pbmpih->biBitCount = 24;
/* 30~33:指定是否压缩, (如果压缩了)采用的压缩格式。
可以为: BI_RGB、BI_RLE4、BI_RLE8、BI_BITFIELDS、BI_PNG、BI_JPEG
有的位图会进行游程长度编码:BI_RLE4、BI_RLE8
压缩可以节省空间, 但不便于编程读写。BI_RGB表示不进行压缩处理 */
pbmpih->biCompression = BI_RGB;
/* 34~37: 位图数据区所占字节数,有固定的计算公式 */
pbmpih->biSizeImage = ((((pbmpih->biWidth * pbmpih->biBitCount) + 31) & ~31) / 8) * pbmpih->biHeight;
/* 38~41: 位图水平分辨率,每米像素数 */
pbmpih->biXPelsPerMeter = 0L;
/* 42~45: 位图垂直分辨率,每米像素数 */
pbmpih->biYPelsPerMeter = 0L;
/* 46~49: 位图实际使用颜色表中颜色数(对于有调色板的位图来说实际上是调色板中颜色项数,
24位真彩色位图不需要调色板, 设为0, 8位灰度位图为256(2^8种颜色)。 */
pbmpih->biClrUsed = 0L;
/* 50~53: 显示位图所需颜色数 */
pbmpih->biClrImportant = 0L;
}
void SetBmpFileHeader(PBITMAPFILEHEADER pbmpfh, const PBITMAPINFOHEADER pbmpih)
{
/* 0~1: 固定值: "BM"(或0x4D42),即表明这是位图(一般以bmp为文件名后缀)*/
pbmpfh->bfType = *(WORD *)"BM";
/* 2~5: 位图文件总大小(占用总字节数, 包括文件头、信息头、调色板、位图数据区占用字节数)*/
pbmpfh->bfSize = pbmpih->biSizeImage + 54 + pbmpih->biClrUsed * sizeof(RGBQUAD);
/* 6~7: 固定值0: 目前没什么用, 可能留作将来扩展。也有的结构体中有这样的域是为了内存对齐 */
pbmpfh->bfReserved1 = 0;
/* 8~9: 固定值 */
pbmpfh->bfReserved2 = 0;
/* 10~13: 位图数据区起始位置, 计算方法为:
位图文件头14个字节+位图信息头40个字节+位图调色板所占字节数,
这里要创建的是一张24位位图(无调色板),故设置为54 也可以。*/
pbmpfh->bfOffBits = 54 + pbmpih->biClrUsed * sizeof(RGBQUAD);
}
int main(void)
{
BITMAPFILEHEADER bmpfh = { 0 }; /* 位图文件头 */
BITMAPINFOHEADER bmpih = { 0 }; /* 位图信息头 */
FILE *fpBmp = NULL;
COLORREF color = RGB(0xf0,0xca,0xa6); /* 天蓝色 */
COLORREF black = 0;
int fillbits;
int w, h;
SetBmpInfoHeader(&bmpih);
SetBmpFileHeader(&bmpfh, &bmpih);
fillbits = ( 4 - ( bmpih.biWidth * 3 ) % 4 ) % 4;
fpBmp = fopen("D:\\rendering.bmp", "wb");
if (NULL == fpBmp) {
perror("fopen failed:");
system("pause>nul");
exit(EXIT_FAILURE);
}
fwrite(&bmpfh, sizeof(BITMAPFILEHEADER), 1, fpBmp); /* 写入位图文件头 */
fwrite(&bmpih, sizeof(BITMAPINFOHEADER), 1, fpBmp); /* 写入位图信息头 */
/* 写入调色板(如果有的话) */
/* 写入位图数据 */
for (h = 0; h < BMP_H; ++h) {
for (w = 0; w < BMP_W; ++w) {
fwrite(&color, 3, 1, fpBmp); /* 将像素值颜色写入位图文件 */
}
/* 边界填充
对于24位位图每个像素占3个字节,且每个扫描行所占字节数必须是4的倍数。
比如,对于一张宽度为21个像素的24色位图, 理论上每扫描行占用21*3=63个字节,
但63不是4的倍数,所以需要在该扫描行的最后填充一个字节的0,凑到64,
这样实际上每扫描行占用64个字节。
fillbits = ( 4 - ( biheader.biWidth * 3 ) % 4 ) % 4; 参考自acepig, 作用是
计算每扫描行需要填充几个字节的0。对于宽度是4的倍数的图片, count为0。
*/
fwrite(&black, 1, fillbits, fpBmp);
}
fclose(fpBmp);
system("mspaint D:\\rendering.bmp");
return 0;
}