首页 > 代码库 > 图像处理之——浮雕效果实现

图像处理之——浮雕效果实现

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
typedef unsigned short WORD;
typedef unsigned long    DWORD;
typedef unsigned char       BYTE;
/*
typedef struct tagBITMAPFILEHEADER {
	WORD    bfType; 
	DWORD   bfSize; 
	WORD    bfReserved1; 
	WORD    bfReserved2; 
	DWORD   bfOffBits; 
} BITMAPFILEHEADER;


typedef struct BMP //其实BMP文件头、位图信息头、颜色信息的结构体在<windows.h>头文件中有
{
unsigned short bfType; //文件标识 2字节 必须为BM 
unsigned int bfSize; //文件大小 4字节 
unsigned short bfReserved1; //保留,每字节以"00"填写 2字节 
unsigned short bfReserved2; //同上 2字节 
unsigned int bfOffBits; //记录图像数据区的起始位置(图象数据相对于文件头字节的偏移量)。 4字节

//40字节
unsigned int biSize; //表示本结构的大小 4字节 
int biWidth; //位图的宽度 4字节 
int biHeight; //位图的高度 4字节 
unsigned short biPlanes; //永远为1 , 2字节 
unsigned short biBitCount; //位图的位数 分为1 4 8 16 24 32 2字节 
unsigned int biCompression; //压缩说明 4字节 
unsigned int biSizeImage; //表示位图数据区域的大小以字节为单位 4字节 
int biXPelsPerMeter; //用象素/米表示的水平分辨率 4字节 
int biYPelsPerMeter; //用象素/米表示的垂直分辨率 4字节 
unsigned int biClrUsed; //位图使用的颜色索引数 4字节 
unsigned int biClrImportant; //对图象显示有重要影响的颜色索引的数目 4字节 

} BMP;
typedef struct tagRGBQUAD {
	BYTE    rgbBlue;
	BYTE    rgbGreen;
	BYTE    rgbRed;
	BYTE    rgbReserved;
} RGBQUAD;
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;


*/
	

BITMAPFILEHEADER fileheader;
unsigned char* pBmpBuf;  //读入图像数据的指针
int bmpWidth;   //图像的宽度
int bmpHeight;   //图像的高度
RGBQUAD* pColorTable;   //颜色表指针
BITMAPINFOHEADER infoHead;
int all_M;
int biBitCount;   //图像类型,像素位数
int line_width;
//BMP bmp_info;
unsigned char *tempbuffer;
int readbmp(char *bmp)
{

	FILE* fp = fopen(bmp,"rb"); 
	if(fp == 0)
	{
		//
	 printf("文件打开失败");
		return 0;
	}
	//跳过位图文件头
	//为什么不需要定义这个
	
  //fseek(fp,sizeof(BITMAPFILEHEADER),0);
	//printf("%s",bmp_info.bfType);
//	printf("%d %d\n",fp->_base,sizeof(BITMAPFILEHEADER));
	//定义位图信息头结构变量,读取位图信息头进内存,存放在变量infoHead中
fread(&fileheader,sizeof(BITMAPFILEHEADER),1,fp);
  fread(&infoHead,sizeof(BITMAPINFOHEADER),1,fp);
	//fread(&bmp_info,sizeof(BMP),1,fp);
	bmpWidth = infoHead.biWidth;
	bmpHeight = infoHead.biHeight;
	biBitCount = infoHead.biBitCount;

	//cout<<biBitCount<<endl;
	printf("%d %d %d\n",bmpWidth,bmpHeight,biBitCount);
	//定义变量,计算图像每行像素所占的字节数(必须为4的倍数)
	//每行字节数
	int lineByte=(bmpWidth * biBitCount/8 + 3)/4 * 4;
	line_width=lineByte;
	//,且颜色表为256
	//if(biBitCount!=8||biBitCount!=24)
		//cout<<"图片格式位数错误,请输入24位或者8位的bmp图片"<<endl;
	//		printf("图片格式有误\n");
	if(biBitCount == 8)
	{
		//申请颜色表所需要的空间,读颜色表进内存
		pColorTable = new RGBQUAD[256];
		fread(pColorTable,sizeof(RGBQUAD),256,fp);
	}
	//申请位图数据所需要的空间,读位图数据进内存
	int m=lineByte*bmpHeight;
	all_M=m;
	pBmpBuf = new unsigned char[m];
	if(fread(pBmpBuf,1,m,fp)==0)
	{

		
	printf("error");
		return 0;
	}
	fclose(fp);
	//for(int i=0;i<m;i++)
	// cout<<pBmpBuf[i];
	return 1;

}
int save_bmp_file(char *name){
	FILE *new_file=fopen(name,"wt+");//可读可写
	if(new_file==NULL){
		printf("文件打开失败\n");
		return -1;
	}
	//保存文件头,信息头,调色板(24位以下才有),位图数据去,现在我默认是保存24位位图

	fwrite(&fileheader,sizeof(BITMAPFILEHEADER),1,new_file);
	fwrite(&infoHead,sizeof(BITMAPINFOHEADER),1,new_file);
	//fwrite(pBmpBuf,1,all_M,new_file);
	fwrite(tempbuffer,1,all_M,new_file);
	if(new_file!=NULL)
		fclose(new_file);

  return 0;
}
void handle_bmp(){
	//for(int i=0;i<bmpHeight) 
	//彩色浮雕效果
	//f(i,j)-f(i-1,j)+常量,常量一般为128,参考:杨淑莹的图像处理书籍
	tempbuffer=new unsigned char[all_M];
	int temp;
	for(int j=0;j<bmpHeight;j++){
		for(int i=0;i<line_width-4;i++){
			temp=0;
			temp=*(pBmpBuf+(bmpHeight-j-1)*line_width+i)-*(pBmpBuf+(bmpHeight-j-1)*line_width+i+3)+128;
			if(temp<0)
				temp=0;
			if(temp>255)
				temp=255;
			*(tempbuffer+(bmpHeight-j-1)*line_width+i+3)=temp;
		}
	}
}
void main(){
	char *filename="f:\\mm2.bmp";
	readbmp(filename);
	char *savefilename="f:\\teste.bmp";
	handle_bmp();
	save_bmp_file(savefilename);
}