C语言实现BMP图像处理(彩色图转灰度图)
更新时间:2021年10月26日 00:00 点击:1649 作者:傻不拉几的程序员
我们知道真彩图不带调色板,每个象素用 3 个字节,表示 R、G、B 三个分量。所以处理很简单,根据 R、G、B 的值求出 Y 值后,将 R、G、B 值都赋值成 Y,写入新图即可。 在YUV 的颜色表示方法中,Y 分量的物理含义就是亮度,它含了灰度图(grayscale)的所有信息,只用 Y 分量就完全能够表示出一幅灰度图来。YUV 和RGB 之间有着如下的对应关系:
再来看看带调色板的彩色图,我们知道位图中的数据只是对应调色板中的一个索引值,我们只需要将调色板中的彩色变成灰度,形成新调色板,而位图数据不用动,就可以了。
以上解释来自于:《数字图像处理编程入门》,代码参考:C语言实现24位彩色图像二值化
#include<stdio.h> #include<windows.h> int main(int argc, char* argv[]) { int bmpHeight; int bmpWidth; unsigned char *pBmpBuf; RGBQUAD *pColorTable; int biBitCount; //读取bmp文件 FILE *fp = fopen("./02.bmp", "rb"); if (fp == 0) return 0; fseek(fp, sizeof(BITMAPFILEHEADER), 0); BITMAPINFOHEADER head; fread(&head, 40, 1, fp); bmpHeight = head.biHeight; bmpWidth = head.biWidth; biBitCount = head.biBitCount; fseek(fp, sizeof(RGBQUAD), 1); int LineByte = (bmpWidth*biBitCount / 8 + 3) / 4 * 4;//保证每一行字节数都为4的整数倍 pBmpBuf = new unsigned char[LineByte*bmpHeight]; fread(pBmpBuf, LineByte*bmpHeight, 1, fp); fclose(fp); //将24位真彩图灰度化并保存 FILE *fp1 = fopen("gray.bmp", "wb"); if (fp1 == 0) return 0; int LineByte1 = (bmpWidth * 8 / 8 + 3) / 4 * 4; //修改文件头,其中有两项需要修改,分别为bfSize和bfOffBits BITMAPFILEHEADER bfhead; bfhead.bfType = 0x4D42; bfhead.bfSize = 14 + 40 + 256 * sizeof(RGBQUAD)+LineByte1*bmpHeight;//修改文件大小 bfhead.bfReserved1 = 0; bfhead.bfReserved2 = 0; bfhead.bfOffBits = 14 + 40 + 256 * sizeof(RGBQUAD);//修改偏移字节数 fwrite(&bfhead, 14, 1, fp1); //将修改后的文件头存入fp1; //修改信息头,其中有两项需要修改,1个位biBitCount:真彩图为24 ,应改成8;另一个是biSizeImage:由于每像素所占位数的变化,所以位图数据的大小发生变化 BITMAPINFOHEADER head1; head1.biBitCount = 8; //将每像素的位数改为8 head1.biClrImportant = 0; head1.biCompression = 0; head1.biClrUsed = 0; head1.biHeight = bmpHeight; head1.biWidth = bmpWidth; head1.biPlanes = 1; head1.biSize = 40; head1.biSizeImage = LineByte1*bmpHeight;//修改位图数据的大小 head1.biXPelsPerMeter = 0; head1.biYPelsPerMeter = 0; fwrite(&head1, 40, 1, fp1); //将修改后的信息头存入fp1; pColorTable = new RGBQUAD[256]; for (int i = 0; i < 256; i++){ pColorTable[i].rgbRed = i; pColorTable[i].rgbGreen = i; pColorTable[i].rgbBlue = i; //是颜色表里的B、G、R分量都相等,且等于索引值 } fwrite(pColorTable, sizeof(RGBQUAD), 256, fp1); //将颜色表写入fp1; //写位图数据 unsigned char *pBmpBuf1; pBmpBuf1 = new unsigned char[LineByte1*bmpHeight]; for (int i = 0; i < bmpHeight; i++){ for (int j = 0; j<bmpWidth; j++){ unsigned char *pb1, *pb2; pb1 = pBmpBuf + i*LineByte + j * 3; int y = *(pb1)*0.299 + *(pb1 + 1)*0.587 + *(pb1 + 2)*0.114; //将每一个像素都按公式y=B*0.299+G*0.587+R*0.114进行转化 pb2 = pBmpBuf1 + i*LineByte1 + j; *pb2 = y; } } fwrite(pBmpBuf1, LineByte1*bmpHeight, 1, fp1); fclose(fp1); system("pause"); return 0; }
实验结果分析:
实验结果分析:真彩色图不带调色板,而灰度图的调色板为256级。所以在修改调色板时需要将RGB三个分量修改为256级,根据YUV颜色空间中Y分量计算。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。
原文出处:https://blog.csdn.net/fengxianghui01/article/details/8507631
上一篇: C++实现bmp格式图像读写
下一篇: C语言实现24位彩色图像二值化
相关文章
- 这篇文章主要为大家详细介绍了C语言实现放烟花的程序,有音乐播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-23
- 本篇文章主要介绍C语言中char的知识,并附有代码实例,以便大家在学习的时候更好的理解,有需要的可以看一下...2020-04-25
- 这篇文章主要介绍了详解如何将c语言文件打包成exe可执行程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-25
- free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
- 这篇文章主要介绍了C语言中计算正弦的相关函数总结,包括正弦和双曲线正弦以及反正弦的函数,需要的朋友可以参考下...2020-04-25
详解C语言中的rename()函数和remove()函数的使用方法
这篇文章主要介绍了详解C语言中的rename()函数和remove()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25- 这篇文章主要介绍了C语言中求和、计算平均值、方差和标准差的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-10
- 本篇文章主要讲解C语言 基本语法,这里提供简单的示例和代码来详细讲解C语言的基本语法,开始学习C语言的朋友可以看一下,希望能够给你带来帮助...2021-09-18
- 这篇文章主要介绍了C语言中send()函数和sendto()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25
- 今天小编就为大家分享一篇C语言实现从文件读入一个3*3数组,并计算每行的平均值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了C语言中memcpy 函数的用法详解的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了使用C语言操作文件的基本函数整理,包括创建和打开以及关闭文件的操作方法,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中查找字符在字符串中出现的位置的方法,分别是strchr()函数和strrchr()函数的使用,需要的朋友可以参考下...2020-04-25
- 很多同学在学习c语言的时候是不是会碰到a++和++a都有甚么作用啊。今天我们就来探讨下...2020-04-25
- 这篇文章主要对C语言中const关键字的用法进行了详细的分析介绍,需要的朋友可以参考下...2020-04-25
- 下面小编就为大家带来一篇C语言实现时间戳转日期的算法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了C语言之整数划分问题(递归法)实例代码的相关资料,需要的朋友可以参考下...2020-04-25
- 本文给大家简单介绍下c实现linux下的数据库备份的方法和具体的源码,十分的实用,有需要的小伙伴可以参考下。...2020-04-25
C语言正则表达式详解 regcomp() regexec() regfree()用法详解
C语言处理正则表达式常用的函数有regcomp()、regexec()、regfree()和regerror(),这里就为大家介绍一下,需要的朋友可以参考一下啊...2020-04-25- 这篇文章主要介绍了c语言实现找最大值最小值位置查找,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-04