位图的读取与保存 C语言 源文件+头文件

位图的读取与保存 C语言 源文件+头文件

有关位图的一些知识:

1、关于颜色表:一般是针对16位以下的图像而设置的,对于16位和16位以上的图像,由于其位图像素数据中直接对对应像素的RGB(A)颜色经行描述,因而省却了调色板。而对于16位以下的图像,由于其位图像素数据中记录的只是调色板索引值,因而需要根据这个索引到调色板去取得相应的RGB(A)颜色,颜色表的作用就是创建调色板。

2、位图的分类:
0,用在JPEG格式中。
1,单色图,调色板中含有两种颜色,也就是黑白图片。
4,16色图
8,256色图,通常说的灰度图。
16,64k图,一般没有调色板,图像数据中每两个字节表示一个像素,5个或6个位表示一个RGB分量。
24,16M真彩色图,无调色板,图像数据中每3个字节表示一个像素,每个字节表示一个RGB分量。
32,4G真彩色,无调色板,每4个字节表示一个像素,相对于24位真彩色图而言,加入了一个透明度,即RGBA模式。

3、关于位图中的字节对其方法:
a、灰度图像:stepWidth = (width + 3)& ~3;
b、16位彩色图:stepWidth = ( width * 3 + 3)& ~3;

4、关于位图的两种形式:底到上型DIB,和顶到下型DIB。底到上型DIB的原点在图像的左下角,而顶到下型DIB的原点在图像的左上角。如果DIB的高度biHeight是一个正值,那么就表示这个DIB是一个底到上型,反之就是顶到下型。(注意:顶到下型DIB位图不能压缩)

.c 源文件

#include <stdio.h>
#include <stdlib.h>
#include "bmp.h"

void readBmp(const char* fileName, unsigned char** raw, int* width, int* height, int* bitCount, int* stepWidth)
{
	BitmapHeader head; 
	FILE *ffp;
	int lineByte, size;
	ffp = fopen(fileName, "rb");
	if(ffp == 0) return;
	fseek(ffp, sizeof(BitmapFileHeader),0);
	fread(&head, sizeof(BitmapHeader), 1, ffp); 
	*width = head.biWidth;
	*height = head.biHeight;
	*bitCount = head.biBitCount;
	*stepWidth = lineByte = (((*width * *bitCount >> 3) + 3) >> 2) << 2;
	size = lineByte * *height;
	if(*bitCount == 8)
		fseek(ffp, 256*sizeof(RGBQUAD1), SEEK_CUR);
	*raw = (unsigned char *)malloc(size);
	size = fread(*raw, 1, size, ffp);
	fclose(ffp);
}

void saveBmp(const char* fileName,unsigned char* raw, int width, int height, int bitCount)
{
	BitmapFileHeader fileHead;
	BitmapHeader head;
	RGBQUAD1 quad[256];
	int colorTablesize;
	int i;
	FILE *file;
	int lineBytes;
	file = fopen(fileName, "wb");
	if(!file) return;
	if(!raw) return;
	lineBytes = (((width * bitCount >> 3) + 3) >> 2) << 2;
	if(bitCount == 8) colorTablesize = 1024;
	else colorTablesize = 0;
	//申请位图文件头结构变量,填写文件头信息
	fileHead.bfType = 0x4D42;//bmp类型
	fileHead.bfSize= sizeof(BitmapFileHeader) + sizeof(BitmapHeader)+ colorTablesize + lineBytes* height;
	fileHead.bfReserved1 = 0;
	fileHead.bfReserved2 = 0;
	fileHead.bfOffBits=54+colorTablesize;
	fwrite(&fileHead, sizeof(BitmapFileHeader),1, file);
	//申请位图信息头结构变量,填写信息头信息
	head.biBitCount= bitCount;
	head.biClrImportant=0;
	head.biClrUsed=0;
	head.biCompression=0;
	head.biHeight= height;
	head.biPlanes=1;
	head.biSize=40;
	head.biSizeImage= lineBytes * height;
	head.biWidth= width;
	head.biXPelsPerMeter=0;
	head.biYPelsPerMeter=0;
	//写位图信息头进内存
	fwrite(&head, sizeof(BitmapHeader),1, file);
	//如果灰度图像,有颜色表,写入文件 
	if (head.biBitCount == 8)
	{
		for (i=0; i<256; i++)
		{
			quad[i].rgbBlue = i;
			quad[i].rgbGreen = i;
			quad[i].rgbRed = i;
			quad[i].rgbReserved = 0;

			fwrite(&quad[i], sizeof(RGBQUAD1), 1, file);
		}
	}
	fwrite(raw, lineBytes * head.biHeight, 1 , file);
	fclose(file);
	return;
}

.h 头文件

#ifndef __Bmp__H
#define __Bmp__H

#pragma pack(push)
#pragma pack(1)

typedef struct tagBitmapFileHeader
{
	short    bfType;         // 位图文件的类型,必须为BM
	int   bfSize;         // 位图文件的大小,以字节为单位
	short    bfReserved1;    // 位图文件保留字,必须为0
	short    bfReserved2;    // 位图文件保留字,必须为0
	int   bfOffBits;      // 位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位
} BitmapFileHeader, *pBitmapFileHeader;

typedef struct tagRGBQUAD1
{ // rgbq 
	unsigned char    rgbBlue;              // 该颜色的蓝色分量
	unsigned char    rgbGreen;             // 该颜色的绿色分量
	unsigned char    rgbRed;               // 该颜色的红色分量
	unsigned char    rgbReserved;          // 保留字节,暂不用
} RGBQUAD1;

//位图信息头
typedef struct tagBitmapInfor
{
	int      biSize;            // 本结构所占用字节数,即sizeof(BITMAPINFOHEADER)
	int       biWidth;           // 位图的宽度,以像素为单位
	int       biHeight;          // 位图的高度,以像素为单位
	short       biPlanes;          // 目标设备的级别,必须为1
	short       biBitCount;        // 每个像素所需的位数,必须是1(双色),4(16色),8(256色)或24(真彩色)之一
	int      biCompression;     // 位图压缩类型,必须是 0(不压缩),1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
	int      biSizeImage;       // 位图的大小,以字节为单位
	int      biXPelsPerMeter;   // 位图水平分辨率,每米像素数
	int       biYPelsPerMeter;   // 位图垂直分辨率,每米像素数
	int      biClrUsed;         // 位图实际使用的颜色表中的颜色数
	int      biClrImportant;    // 位图显示过程中重要的颜色数
} BitmapHeader, *pBitmapHeader;
#pragma pack(pop)

void readBmp(const char* fileName, unsigned char** raw, int* width, int* height,int* bitCount, int* stepWidth);
void saveBmp(const char* fileName,unsigned char* raw, int width, int height, int bitCount);
#endif



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值