#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); }
原文地址:http://blog.csdn.net/sn_zzy/article/details/26376459