8bit 灰阶BMP存取

修改bitmap 头文件,使其符合标准C ,适用于跨平台开发

bitmap.h

#ifndef _BMP_HEADER_DEF_H_
#define _BMP_HEADER_DEF_H_
#pragma pack(push,1)
typedef int LONG;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef unsigned char BYTE;

typedef struct tagBITMAPFILEHEADER{
	WORD	bfType;
	DWORD	bfSize;
	WORD	bfReserved1;
	WORD	bfReserved2;
	DWORD	bfOffBits;
}BITMAPFILEHEADER,*PBITMAPFILEHEADER;

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,*PBITMAPINFOHEADER;

typedef struct tagRGBQUAD{
	BYTE rgbBlue;
	BYTE rgbGreen;
	BYTE rgbRed;
	BYTE rgbReserved;
}RGBQUAD;
#pragma pack(pop)
#endif

存取8bit BMP图像实现

#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

#include "bitmap.h"

int write_bmp(const char *path ,BYTE * data,int w,int h)
{
	FILE *fd=fopen(path,"wb+");
	int ret=0,len,i;
	len=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256+w*h;
	
	BYTE *image=(BYTE *)malloc(len);

	BITMAPFILEHEADER *pfh=(BITMAPFILEHEADER *)image;
	BITMAPINFOHEADER *pinfo=(BITMAPINFOHEADER *)(image+sizeof(BITMAPFILEHEADER));
	RGBQUAD *rgb=(RGBQUAD*)(image+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
	
	pfh->bfType=0x4d42;
	pfh->bfSize=len;
	pfh->bfReserved1=pfh->bfReserved2=0;
	pfh->bfOffBits=len-w*h;
	
	pinfo->biSize=sizeof(BITMAPINFOHEADER);
	pinfo->biWidth=w;
	pinfo->biHeight=h;
	pinfo->biPlanes=1;
	pinfo->biBitCount=8;
	pinfo->biCompression=0;
	pinfo->biSizeImage=w*h;
	pinfo->biXPelsPerMeter=3780;
	pinfo->biYPelsPerMeter=3780;
	pinfo->biClrUsed=256;
	pinfo->biClrImportant=0;	
	
	for(i=0;i<256;i++){
		rgb[i].rgbBlue=i;
		rgb[i].rgbGreen=i;
		rgb[i].rgbRed=i;
		rgb[i].rgbReserved=0;
	}
	
	memcpy(image+pfh->bfOffBits,data,w*h);

	if(!fd){
		perror(path);
		exit(EXIT_FAILURE);
	}
	ret=fwrite(image,1,len,fd);
	if(ret!=len){
		perror(path);
		exit(EXIT_FAILURE);
	}
	fclose(fd);

	free(image);
	return ret;
}

unsigned char * load_bmp(const char *path, int *w,int *h)
{
	FILE *fd;
	struct stat sb;
	unsigned char *buffer,*pbuff;
	size_t size,n;

	fd=fopen(path,"rb");
	if(!fd){
		perror(path);
		exit(EXIT_FAILURE);
	}

	if(stat(path,&sb)){
		perror(path);
		exit(EXIT_FAILURE);
	}
	size=sb.st_size;

	buffer=malloc(size);
	if(!buffer){
		fprintf(stderr, "Unable to allocate %lld bytes\n",(long long)size);
		exit(EXIT_FAILURE);
	}

	n=fread(buffer,1,size,fd);
	if(n!=size){
		perror(path);
		exit(EXIT_FAILURE);
	}

	fclose(fd);

	BITMAPFILEHEADER *pfh=(BITMAPFILEHEADER *)buffer;

	assert(sizeof(BITMAPFILEHEADER)==14);
	//printf("the struct BITMAPFILEHEADER len!=14,please change mem alignment,like this #pragma pack(1)\n") ;

	if(pfh->bfType!=0x4d42)return NULL;

	BITMAPINFOHEADER *pinfo=(BITMAPINFOHEADER*)(buffer+sizeof(BITMAPFILEHEADER));

	*w=pinfo->biWidth;
	*h=pinfo->biHeight;

	//printf("load_file heilght=%d,%d\n",pinfo->biWidth*pinfo->biHeight,1);
	pbuff=malloc(pinfo->biWidth*pinfo->biHeight);
	memcpy(pbuff,buffer+pfh->bfOffBits,pinfo->biWidth*pinfo->biHeight);

#if 0	
	printf("pfh->bfOffBits=%d\n",pfh->bfOffBits);
	printf("pfh->bfSize=%d\n",pfh->bfSize);

	printf("pinfo->biSize=%d\n",pinfo->biSize);
	printf("pinfo->biClrImportant=%d\n",pinfo->biClrImportant);

	printf("struct len=%ld\n",sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
#endif
	
	free(buffer);

	return pbuff;
}
#if 1
int main(int argc,char **argv)
{
	int w,h;	
	unsigned char *image=load_bmp("test1.bmp",&w,&h);	
	printf("w=%d,h=%d\n",w,h);
	write_bmp("save.bmp" ,image,w,h);
	free(image);
	
	return 0;
}
#endif

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值