c++创建BMP文件并写入数据

参考:http://zhidao.baidu.com/link?url=K0X3GJIiAdhEJ3UheJ8RTcEKrApKn2B6dRkcEpkVspNfebrm345Ltx7_VUJqDs9QYA-0MOTBMBLcOm-h_MD7sa

参考:http://blog.csdn.net/lanbing510/article/details/8176231

最近要看看自己生成的图像,想输出到一个bmp文件。

1、BMP文件概述

BMP(Bitmap-File)图形文件,又叫位图文件,是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各图像绘制操作都是以BMP为基础的。一个BMP文件由四部分组成:

  • 位图文件头
  • 位图信息段
  • 调色板
  • 位图数据

一个BMP文件,可以用代码表示,如下:

typedef struct tagBITMAP_FILE{

BITMAPFILEHEADER bitmapheader;      BITMAPINFOHEADER bitmapinfoheader;      PALETTEENTRY palette[256];      UCHAR *buffer;   

} BITMAP_FILE;

二、BMP文件的写入

将一个32位数据写入到BMP。

#pragma pack(2)//必须得写,否则sizeof得不到正确的结果
typedef unsigned char  BYTE;
typedef unsigned short WORD;
typedef unsigned long  DWORD;
typedef long    LONG;
typedef struct {
	WORD    bfType;
	DWORD   bfSize;
	WORD    bfReserved1;
	WORD    bfReserved2;
	DWORD   bfOffBits;
} BITMAPFILEHEADER;

typedef struct {
	DWORD      biSize;
	LONG       biWidth;
	LONG       biHeight;
	WORD       biPlanes;
	WORD       biBitCount;
	DWORD      biCompression;
	DWORD      biSizeImage;
	LONG       biXPelsPerMeter;
	LONG       biYPelsPerMeter;
	DWORD      biClrUsed;
	DWORD      biClrImportant;
} BITMAPINFOHEADER;

void saveBitmap(int w, int h,unsigned char *pData,int nDatasize )
{

	// Define BMP Size
	const int height = w;
	const int width = h;
	const int size = nDatasize;
	double x, y;
	int index;

	// Part.1 Create Bitmap File Header
	BITMAPFILEHEADER fileHeader;

	fileHeader.bfType = 0x4D42;
	fileHeader.bfReserved1 = 0;
	fileHeader.bfReserved2 = 0;
	fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + size;
	fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

	// Part.2 Create Bitmap Info Header
	BITMAPINFOHEADER bitmapHeader = { 0 };

	bitmapHeader.biSize = sizeof(BITMAPINFOHEADER);
	bitmapHeader.biHeight = -height;
	bitmapHeader.biWidth = width;
	bitmapHeader.biPlanes = 1;
	bitmapHeader.biBitCount = 32;
	bitmapHeader.biSizeImage = size;
	bitmapHeader.biCompression = 0; //BI_RGB

	// Write to file
	FILE *output = fopen("output.bmp", "wb");

	if (output == NULL)
	{
		printf("Cannot open file!\n");
	}
	else
	{
		fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, output);
		fwrite(&bitmapHeader, sizeof(BITMAPINFOHEADER), 1, output);
		fwrite(pData, size, 1, output);
		fclose(output);
	}
}

#pragma pack(2)必须要加。bfType是2个字节,对应“BM”,后4个字节是文件大小,又对应4字节。如果不设定对齐方式,而按默认的8字节或4字节对应,这些属性就错位了,而别人又是按标准来读取的,对齐方式不同,自然出错。一般情况下的编程之所以不考虑这些问题,是因为读取和保存都是你个人完成的,对齐方式是一样的,自然不出错。而这里你生成的图片可能还要供别人使用,自然要严格遵守标准。

将一个正弦曲线写入24位的BMP。

void saveBitmap()
{
	// Define BMP Size
	const int height = 600;
	const int width = 800;
	const int size = height * width * 3;
	double x, y;
	int index;

	// Part.1 Create Bitmap File Header
	BITMAPFILEHEADER fileHeader;

	fileHeader.bfType = 0x4D42;
	fileHeader.bfReserved1 = 0;
	fileHeader.bfReserved2 = 0;
	fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + size;
	fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

	// Part.2 Create Bitmap Info Header
	BITMAPINFOHEADER bitmapHeader = { 0 };

	bitmapHeader.biSize = sizeof(BITMAPINFOHEADER);
	bitmapHeader.biHeight = height;
	bitmapHeader.biWidth = width;
	bitmapHeader.biPlanes = 3;
	bitmapHeader.biBitCount = 24;
	bitmapHeader.biSizeImage = size;
	bitmapHeader.biCompression = 0; //BI_RGB

	// Part.3 Create Data
	BYTE *bits = (BYTE *)malloc(size);

	// Clear
	memset(bits, 0xFF, size);

	// Sin Graph
	for (x = 0; x < 800; x += 0.5)
	{
		y = sin(x / 100.0) * 200 + 300;
		index = (int)y * 800 * 3 + (int)x * 3;

		bits[index + 0] = 255; // Blue
		bits[index + 1] = 0;   // Green
		bits[index + 2] = 0;   // Red
	}

	// Write to file
	FILE *output = fopen("output.bmp", "wb");

	if (output == NULL)
	{
		printf("Cannot open file!\n");
	}
	else
	{
		fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, output);
		fwrite(&bitmapHeader, sizeof(BITMAPINFOHEADER), 1, output);
		fwrite(bits, size, 1, output);
		fclose(output);
	}
}

注意点:

图象的高度,以象素为单位。这个值除了用于描述图像的高度之外,它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明图像是倒向的,即:数据的第一行其实是图像的最后一行,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也就是时,高度值是一个正数。

时间: 2024-08-04 08:46:47

c++创建BMP文件并写入数据的相关文章

C#创建Excel文件并将数据导出到Excel文件

C#创建Excel文件,这里实际上是从资源中提取一个事先创建好的Excel文件,文件提取成功后,使用OleDb方法连接Excel,向Excel文件中写入数据. 创建解决方案 菜单>新建>项目>Windows窗体应用程序: 添加相关组件: 添加两个DataGridView,一个TextBox,两个按钮 ,如下图: 添加Excel资源: 先在文件夹中新建一个Excel文件,在Sheet1表的第一行设置列名: 双击"Resources.resx"文件打开资源文件视图: 添加

计算机二级-C语言-程序填空题-190117记录-对文件的处理,复制两个文件,往新文件中写入数据。

//给定程序的功能是,调用函数fun将指定源文件中的内容赋值到指定目标文件中,复制成功时函数返回1,失败时返回0,把复制的内容输出到终端屏幕.主函数中源文件名放在变量sfname中,目标文件名放在变量tfname中. //重难点:对文件的处理.如何判断文件是否达到末尾,如何往文件中写入数据. 1 #include <stdio.h> 2 #include <stdlib.h> 3 int fun(char *source, char *target) 4 { FILE *fs,*f

java io流 创建文件、写入数据、设置输出位置

java io流 创建文件 写入数据 改变system.out.print的输出位置 //创建文件 //写入数据 //改变system.out.print的输出位置 import java.io.*; public class Index{ public static void main(String[] args) throws Exception{ /** * 存储为二进制,给计算机看的 */ //创建文件 DataOutputStream sjl = new DataOutputStrea

如何使用Java创建Excel(.xls 和 .xlsx)文件 并写入数据

1,需要依赖的jar包, <!-- POI(operate excel) start --> <!-- the version of the following POI packages must be consistent --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17&

C# 创建text文本并写入数据

/// <summary> /// 创建TXT文本并往里面写入数据 /// </summary> /// <param name="FileName">要创建的文件名,不要后缀名</param> protected void WriteTxt(string FileName) { Encoding code = Encoding.GetEncoding("gb2312");  //编码格式 string htmlfil

java实现赋值excel模板,并在新文件中写入数据,并且下载

/** * 生成excel并下载 */ public void exportExcel(){ File newFile = createNewFile(); //File newFile = new File("d:/ss.xls"); //新文件写入数据,并下载***************************************************** InputStream is = null; HSSFWorkbook workbook = null; HSSFSh

Google多线程面试题: 4个线程向4个文件里写入数据, 每个线程只能写一个值

By Long Luo 个人博客链接 最近在学习Java多线程时,遇到了一个下面的笔试题,题目如下: 编写一个程序,程序会启动4个线程,向4个文件A,B,C,D里写入数据,每个线程只能写一个值. 线程A:只写A 线程B:只写B 线程C:只写C 线程D:只写D 4个文件A,B,C,D. 程序运行起来,4个文件的写入结果如下: A:ABCDABCD... B:BCDABCDA... C:CDABCDAB... D:DABCDABC... 网上搜索了下,好像还是一个Google笔试题,这个问题涉及到的

lua向文件中写入数据,进行记录

function readfile(path) local file = io.open(path, "r") if file then local content = file:read("*a") io.close(file) return content end return nil end function writefile(path, content, mode) mode = mode or "w+b" local file = i

C#创建txt文件并写入内容

以注册登录为例 using System.Text; 1.注册 //注册 public string registered(string username,string password) { //判断是否已经有了这个文件 if (!System.IO.File.Exists("c:\\users\\administrator\\desktop\\webapplication1\\webapplication1\\testtxt.txt")) { //没有则创建这个文件 FileStr