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)就是灰度图了。
浮点算法: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,
//可以输入文件名的源代码,有些变量定义进行了完善fread和fwrite的区别
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "windows.h"
#include "conio.h"
typedef struct{
unsigned char b;
unsigned char r;
unsigned char g;
}pixel;
pixel a[640][480];
unsigned char aa[640][480];
void main()
{
BITMAPFILEHEADER FILEH;
BITMAPINFOHEADER INFOH;
RGBQUAD RGBH[256];
char name[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);
int LEN1=sizeof(BITMAPFILEHEADER);
int LEN2=sizeof(BITMAPINFOHEADER);
int X,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)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论