BMP图像由彩图变为灰度图.docx
- 文档编号:10303365
- 上传时间:2023-02-10
- 格式:DOCX
- 页数:11
- 大小:17.79KB
BMP图像由彩图变为灰度图.docx
《BMP图像由彩图变为灰度图.docx》由会员分享,可在线阅读,更多相关《BMP图像由彩图变为灰度图.docx(11页珍藏版)》请在冰豆网上搜索。
BMP图像由彩图变为灰度图
Date:
6月21日
任务:
BMP真彩图像转为灰度图
一,算法及公式:
1,什么叫灰度图?
任何颜色都有红、绿、蓝三原色组成,假如原来某点的颜色为RGB(R,G,B),那么,我们可以通过下面几种方法,将其转换为灰度:
浮点算法:
Gray=R*0.3+G*0.59+B*0.11
整数方法:
Gray=(R*30+G*59+B*11)/100
移位方法:
Gray=(R*28+G*151+B*77)>>8;
平均值法:
Gray=(R+G+B)/3;
仅取绿色:
Gray=G;
通过上述任一种方法求得Gray后,将原来的RGB(R,G,B)中的R,G,B统一用Gray替换,形成新的颜色RGB(Gray,Gray,Gray),用它替换原来的RGB(R,G,B)就是灰度图了。
2,改变象素矩阵的RGB值,来达到彩色图转变为灰度图
加权平均值算法:
根据光的亮度特性,其实正确的灰度公式应当是
R=G=B=R*0.299+G*0.587+B0.144
为了提高速度我们做一个完全可以接受的近似,公式变形如下:
R=G=B=(R*3+G*6+B)/10
3,真正的24位真彩图与8位的灰度图的区别就在于,真彩图文件中没有调色板,灰度图有调色板,真彩图中的象素矩阵是RGB值,灰度图中的象素矩阵是调色板索引值。
源代码1只简单的改变象素矩阵的RGB值,来达到彩色图转为灰度图,并没有添加调色板。
源代码2添加了调色板。
二,源代码
1,
//可以输入文件名的源代码,有些变量定义进行了完善
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"windows.h"
#include"conio.h"
typedefstruct{
unsignedcharb;
unsignedcharr;
unsignedcharg;
}pixel;
pixela[640][480];
unsignedcharaa[640][480];
voidmain()
{
BITMAPFILEHEADERFILEH;
BITMAPINFOHEADERINFOH;
RGBQUADRGBH[256];
charname[11];
char*fname[11];
printf("输入需要转换的图片名:
");
scanf("%s",&name);
*fname=name;
strcat(*fname,".bmp");
printf("%s",*fname);
FILE*fp;
if((fp=fopen(*fname,"rb"))==NULL)
{
//if((fp=fopen(*fname,"wb"))==NULL)//防止首次进入时初始化失败
//{
printf("打开文件%s失败!
按任意键返回主菜单!
",fname);
getch();
exit
(1);
//}
}
printf("%s",*fname);
intLEN1=sizeof(BITMAPFILEHEADER);
intLEN2=sizeof(BITMAPINFOHEADER);
intX,Y;
printf("\nlen=%d,%d\n",LEN1,LEN2);
fread(&FILEH,sizeof(BITMAPFILEHEADER),1,fp);
fread(&INFOH,sizeof(BITMAPINFOHEADER),1,fp);
X=INFOH.biWidth;
Y=INFOH.biHeight;
//printf("%d*%d",X,Y);
if(FILEH.bfType!
=0x4d42)
{
fclose(fp);
printf("文件头不正确,不是bmp!
");
exit
(1);
}
if(INFOH.biBitCount!
=24&&INFOH.biBitCount!
=8)
{
fclose(fp);
printf("信息头不正确,不是bmp!
");
exit
(1);
}
//*RGBH=A;
unsignedcharblue,green,red,color;
intj,k;
if(INFOH.biBitCount==8)
{
fread(&RGBH,sizeof(RGBQUAD),256,fp);
for(j=0;j for(k=0;k { fread(&color,1,1,fp); red=RGBH[color].rgbRed; green=RGBH[color].rgbGreen; blue=RGBH[color].rgbBlue; aa[j][k]=(unsignedchar)(0.299*(float)red+0.574*(float)green+0.114*(float)blue); } } if(INFOH.biBitCount==24) { for(j=0;j for(k=0;k { fread(&blue,1,1,fp); fread(&green,1,1,fp); fread(&red,1,1,fp); a[j][k].b=blue; a[j][k].g=green; a[j][k].r=red; aa[j][k]=(unsignedchar)(0.299*(float)red+0.574*(float)green+0.114*(float)blue); } } //printf("ok"); fclose(fp); printf("输入输出的灰度图片名: "); scanf("%s",&name); strcat(*fname,".bmp"); if((fp=fopen(*fname,"wb"))==NULL) { fclose(fp); printf("打开图片124.bmp失败"); exit (1); } INFOH.biBitCount=8; fwrite(&FILEH,LEN1,1,fp); fwrite(&INFOH,LEN2,1,fp); intm=0; for(inti=0;i<256;i++) { fwrite(&i,1,1,fp); fwrite(&i,1,1,fp); fwrite(&i,1,1,fp); fwrite(&m,1,1,fp); } for(j=0;j for(k=0;k { fwrite(&aa[j][k],1,1,fp); } fclose(fp); printf("生成灰度图%s成功! \n",*fname); } 2, bmpFormat.h -------------------------------------------- #ifndef_BMPTEST_H_ #define_BMPTEST_H_ #include typedefunsignedcharBYTE; typedefunsignedshortWORD; typedefstruct{ longimageSize; longblank; longstartPostition; }BmpHead; typedefstruct{ longlength; longwidth; longheight; WORDcolorPlane; WORDbitColor; longzipFormat; longreadSize; longxPels; longyPels; longcolorUse; longcolorImportant; }InfoHead; typedefstruct{ BYTErgbBlue; BYTErgbGreen; BYTErgbRed; BYTErgbReserved; }RGBMixPlate; #endif -------------------------------------------- create.c -------------------------------------------- #include"bmpFormat.h" #include #include intmain(intargc,char*argv[]){ //tiff文件涉及变量 TIFF*image;//tiff文件指针 uint32width,height;//图片的宽度和高度 char*buffer;//保存tiff文件中的图像灰度信息缓存 tsize_tstripSize;//tiff中图像的条大小 unsignedlongbufferSize;//缓存大小 intstripMax,stripCount;//图像总共的条数和读条信息时的控制变量 unsignedlongimageOffset,result;//读文件信息时的控制变量和每次读的结果 //循环控制变量 unsignedinti; unsignedintj; //bmp文件涉及变量 BmpHeadbmphead;//bmp文件头(不包括固定信息) InfoHeadinfohead;//bmp信息头 RGBMixPlate*color;//调色板 BYTE*index;//图像数据在调色板中的索引值 FILE*bmp;//bmp文件指针 charbm[2]={'B','M'};//bmp文件头中的一块固定信息,表示这是一张BMP图片 ‘ //打开tiff图片 if((image=TIFFOpen(argv[1],"r"))==NULL){ fprintf(stderr,"Couldnotopenincomingimage\n"); return-1; } //获取图片的宽度和高度 TIFFGetField(image,TIFFTAG_IMAGEWIDTH,&width); TIFFGetField(image,TIFFTAG_IMAGELENGTH,&height); stripSize=TIFFStripSize(image);//每条的大小 stripMax=TIFFNumberOfStrips(image);//一共有多少条 imageOffset=0;//后面读取文件信息时使用的偏移量 //根据文件信息申请相应的数据空间 bufferSize=TIFFNumberOfStrips(image)*stripSize; if((buffer=(char*)malloc(bufferSize))==NULL) { fprintf(stderr,"Couldnotallocateenoughmemoryfortheuncompressedimage\n"); return-1; } //读取文件中的灰度信息 for(stripCount=0;stripCount { if((result=TIFFReadEncodedStrip(image,stripCount,buffer+imageOffset,stripSize))==-1) { fprintf(stderr,"Readerroroninputstripnumber%d\n",stripCount); return-1; } imageOffset+=result; } //bmp文件头成员赋值 bmphead.blank=0;//保留字,为0 bmphead.imageSize=14+40+4*256+width*height;//图片的大小=文件头大小+信息头大小+调色板大小+实际图片大小 bmphead.startPostition=14+40+4*256;//图片实际数据相对于文件头的偏移量 //bmp信息头成员赋值(可参见BMP文件解析每个成员的定义) infohead.length=40; infohead.width=width; infohead.height=height; infohead.colorPlane=1; infohead.bitColor=8; infohead.zipFormat=0; infohead.readSize=width*height; infohead.xPels=400; infohead.yPels=300; infohead.colorUse=0; infohead.colorImportant=0; //申请调色板和数据域空间 color=(RGBMixPlate*)malloc(sizeof(RGBMixPlate)*256); index=(BYTE*)malloc(sizeof(BYTE)*infohead.readSize); //生成256色灰度调色板 for(i=0;i<256;i++) { color[i].rgbBlue=i; color[i].rgbGreen=i; color[i].rgbRed=i; color[i].rgbReserved=0; } //256色灰度bmp的数据信息实际就是该灰度在相应灰度值的调色板中的颜色 for(i=0;i for(j=0;j index[i*width+j]=buffer[(height-1-i)*width+j];//tiff图片是从左上到右下,bmp图片是从左下到右上 //创建bmp图片 bmp=fopen(argv[2],"wb"); if(bmp==NULL) { printf("opennewfileerror\n"); return-1; } //写入相应的数据 fwrite(bm,1,2,bmp); fwrite(&bmphead,1,12,bmp); fwrite(&infohead,1,40,bmp); fwrite(color,1,256*sizeof(color),bmp); fwrite(index,1,infohead.readSize,bmp); fclose(bmp); //释放有关资源 free(buffer); free(color); free(index); TIFFClose(image); fclose(bmp); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- BMP 图像 彩图 变为 灰度