任意宽度灰度BMP图像读写 V1

来源:互联网 发布:js 计数器 编辑:程序博客网 时间:2024/05/20 02:29

       一般BMP图像读写程序只能正确读写宽度为4的倍数的图像,而在图像处理领域所用到的图像宽度不一定满足4的倍数。我在一般BMP图像读写程序基础上进行了改进,使得程序可以读写任意宽度的灰度BMP图像。特分享给大家,希望能够给大家带来帮助。

头文件:myRdWtIm.h
#ifndef RWBMP_H#define RWBMP_H#include <windows.h>#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>BYTE *Read8bitbmp(char *bmpName,int *bmpWidth,int *bmpHeight);//读BMP图像bool Writebitmapbmp(unsigned char *imgBuf, int width, int height, char *bmpName);//写BMP图像#endif

源文件:myRdWtIm.cpp

#include "myRdWtIm.h"/*------------------------------------------------*函数名称:*readBmp()**函数参数:*char *bmpName -文件名字及路径*int *bmpWidth -图像宽度指针变量*int *bmpHeight -图像高度指针变量**返回值:*unsigned char * -有效图像数据指针**说明:*(1)给定一个图像文件名及其路径,读图像的位图数据、宽、高、颜色表及每像素*位数等数据进内存。*(2)该读程序仅针对灰度图像(biBitCount=8)格式------------------------------------------------*/BYTE* Read8bitbmp(char *bmpName,int *bmpWidth,int *bmpHeight){//二进制读方式打开指定的图像文件FILE *fp=fopen(bmpName,"rb");if(fp==0) return 0;//跳过位图文件头结构BITMAPFILEHEADERfseek(fp, sizeof(BITMAPFILEHEADER),0);//moves the file pointer to a specified location//定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中BITMAPINFOHEADER head;fread(&head, sizeof(BITMAPINFOHEADER), 1,fp); //获取图像宽、高等信息*bmpWidth = head.biWidth;//位图的宽度,以像素为单位*bmpHeight = head.biHeight;//位图的高度,以像素为单位//定义变量,计算图像每行像素所占的字节数(必须是4的倍数)int biBitCount=8;//8位灰度图像int lineByte=((*bmpWidth)*biBitCount/8+3)/4*4;//灰度图像有颜色表,且颜色表表项为256RGBQUAD *pColorTable=new RGBQUAD[256];//申请颜色表所需要的空间fread(pColorTable,sizeof(RGBQUAD),256,fp);//读颜色表进内存//申请位图数据所需要的空间,读位图数据进内存unsigned char *pBmpBuf=new unsigned char[lineByte*(*bmpHeight)];fread(pBmpBuf,1,lineByte*(*bmpHeight),fp);//关闭文件fclose(fp);//提取有效数据,并返回if (*bmpWidth<lineByte){unsigned char *pBmpBufData=new unsigned char[(*bmpWidth)*(*bmpHeight)];for (int i=0;i<*bmpHeight;i++){for (int j=0;j<*bmpWidth;j++){pBmpBufData[i*(*bmpWidth)+j]=*(pBmpBuf+i*lineByte+j);//第一种赋值方法//*(pBmpBufData+i*(*bmpWidth)+j)=*(pBmpBuf+i*lineByte+j);//第二种赋值方法}}return pBmpBufData;//返回提取的有效数据}else{return pBmpBuf;//返回有效数据}}/*------------------------------------------------*函数名称:*saveBmp()**函数参数:*unsigned char *imgBuf-待存盘的位图数据*   int width-以像素为单位待存盘位图的宽*   int height-以像素为单位待存盘位图高*char *bmpName-文件名字及路径**返回值:*   0为失败,1为成功**说明:*1.给定一个图像的位图数据、宽、高等信息,将其写到指定文件中。*2.该读程序仅针对灰度图像(biBitCount=8)格式------------------------------------------------*/bool Writebitmapbmp(unsigned char *imgBuf, int width, int height, char *bmpName) {//如果位图数据指针为0,则没有数据传入,函数返回if(!imgBuf) return 0;int biBitCount=8;//每个像素所占的位数(bit)//颜色表大小,以字节为单位,灰度图像颜色表为1024字节int colorTablesize=1024;//待存储图像数据每行字节数为4的倍数int lineByte=(width * biBitCount/8+3)/4*4;//以二进制写的方式打开文件FILE *fp=fopen(bmpName,"wb");if(fp==0) return 0;//申请位图文件头结构变量,填写文件头信息BITMAPFILEHEADER fileHead;fileHead.bfType=0x4D42;//bmp类型//bfSize是图像文件4个组成部分之和fileHead.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTablesize+lineByte*height;fileHead.bfReserved1=0;fileHead.bfReserved2=0;//bfOffBits是图像文件前3个部分所需空间之和fileHead.bfOffBits=54+colorTablesize;//写文件头进文件fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp);//申请位图信息头结构变量,填写信息头信息BITMAPINFOHEADER head;head.biSize=40;//本结构的长度head.biWidth=width;//位图的宽度,以像素为单位head.biHeight=height;//位图的宽度,以像素为单位head.biPlanes=1;//目标设备的级别,必须是1head.biBitCount=8;//每个像素所占的位数(bit),其值必须为1(黑白图像),4(16色图),8(256色),24(真彩色图)head.biCompression=BI_RGB;//位图压缩类型,有效的值为BI_RGB(未经压缩)、BI_RLE4,BI_RLE8,BI_BITFIEDS(均为Windows定义常量)。head.biSizeImage=lineByte*height;//实际的位图数据占用的字节数head.biXPelsPerMeter=0;//指定目标数据的水平分辨率,单位是像素/米。head.biYPelsPerMeter=0;////指定目标数据的垂直分辨率,单位是像素/米。head.biClrUsed=0;//位图实际用到的颜色数,如果该值为零,则用到的颜色数为2的biBitCount次幂head.biClrImportant=0;//位图显示过程中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。//写位图信息头进内存fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp);//申请颜色表所需要的空间,写颜色表进文件RGBQUAD *pColorTable=new RGBQUAD[256];for (int i=0;i<256;i++){pColorTable[i].rgbRed=i;pColorTable[i].rgbGreen=i;pColorTable[i].rgbBlue=i;pColorTable[i].rgbReserved=0;}fwrite(pColorTable,sizeof(RGBQUAD),256,fp);//判断位图数据宽度是否正确,并写数据进入BMPif (width<lineByte)//如果有效数据宽度小于BMP格式要求宽度{unsigned char *imgBufBMP=new unsigned char [lineByte*height];//将有效数据赋给用于写BMP的数据空间for (int i=0;i<height;i++){for (int j=0;j<width;j++){*(imgBufBMP+i*lineByte+j)=*(imgBuf+i*width+j);}}//将大于有效数据宽度的部分补0for (int i=0;i<height;i++){for (int j=width;j<lineByte;j++){*(imgBufBMP+i*lineByte+j)=0;}}//写BMP格式要求的图数据写进文件fwrite(imgBufBMP, height*lineByte, 1, fp);}else{//写有效图数据写进文件fwrite(imgBuf, height*lineByte, 1, fp);}//关闭文件fclose(fp); return 1;}

愿上帝祝福你!


原创粉丝点击