/**
* 程序名: Convert.cpp
* 功  能: 将24位真彩色图转换为8位灰度图片
*  测试图片test1.bmp放到工程目录下
*/
#include <iostream>
#include <fstream>
#include <windows.h>
#include <cstring>
using namespace std;
BITMAPFILEHEADER bmpFileHeader; //位图文件头
BITMAPINFOHEADER bmpInfoHeader; //位图信息头
RGBQUAD *pColorTable; //颜色表,注:24位真彩色图无颜色表
unsigned char *pBmpData; //位图数据
unsigned char *pGrayData; //灰度图像数据
/**
* 函数名: readBmp
* 参  数: fileName -- 要转换的图片名
* 功  能: 读取fileName文件信息,读取成功返回TRUE,反之,返回FALSE
*/
bool readBmp(char *fileName)
{
FILE *fp = fopen(fileName,"rb"); //以二进制读方式打开
if(NULL == fp)
{
cout<<"File is opened failure!"<<endl;
return FALSE;
}
//读取数据
fread(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
fread(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,fp);
pBmpData = new unsigned char[bmpInfoHeader.biSizeImage];   //申请空间,大小为位图数据大小
fread(pBmpData,sizeof(unsigned char),bmpInfoHeader.biSizeImage,fp);
fclose(fp); //不要忘了关闭文件
return TRUE;
}
/**
* 函数名: convert
* 功  能: 实现24位真彩色图到灰度图的转换
*/
void convert()
{
//因为转换后多了个颜色表,所以要改变,对bmp文件结构不清楚的看笔记1
bmpFileHeader.bfOffBits += (sizeof(RGBQUAD) * 256); 
//biSizeImg存储的为位图数据占用的字节数,转换为灰度图像后值发生改变,
//因为24为真彩色位图数据的一个像素用3各字节表示,灰度图像为1个字节
bmpInfoHeader.biBitCount = 8;
int lineBytes = (bmpInfoHeader.biWidth * 8 + 31) / 32 * 4;
int oldLineBytes = (bmpInfoHeader.biWidth * 24 + 31) / 32 * 4;
int oldSize = bmpInfoHeader.biSizeImage; //原图数据大小
bmpInfoHeader.biSizeImage = lineBytes * bmpInfoHeader.biHeight;
//定义灰度图像的颜色表
pColorTable = new RGBQUAD[256];
for(int i = 0; i < 256; i++ )
{
(*(pColorTable + i)).rgbBlue = i;
(*(pColorTable + i)).rgbGreen = i;
(*(pColorTable + i)).rgbRed = i;
(*(pColorTable + i)).rgbReserved = 0;
}
//将RGB转换为灰度值
int red,green,blue;
BYTE gray;
pGrayData = new unsigned char[bmpInfoHeader.biSizeImage];
memset(pGrayData,0,bmpInfoHeader.biSizeImage);
//这里要注意,Windows规定一个扫描行所占的字节数必须是
//4的倍数(即以long为单位),不足的以0填充,所以如果当前biWidth如果不是
//4的倍数时,要在后面补0直到为4的倍数
for(i = 0; i < bmpInfoHeader.biHeight; i++ )
{
//位图数据(pBmpData)中存储的实际像素数为biWidth个,而一个扫描行要lineByte个字节,
//多余出来的是上面补的0,所以要转换的要是实际的像素数,
//因为转换前后biWidth是相同的,而lineByte是不同的,也就是后面补的0不同
//如果还有疑惑,请留言提问,我会即时回复
for(int j = 0; j < bmpInfoHeader.biWidth; j++ )
{
red = *(pBmpData + i*oldLineBytes + 3*j );
green = *(pBmpData + i*oldLineBytes + 3*j + 1);
blue = *(pBmpData + i*oldLineBytes + 3*j + 2);
gray = (BYTE)((77 * red + 151 * green + 28 * blue) >> 8);
*(pGrayData + i*lineBytes + j) = gray;
}
}

}
/**
* 函数名: writeBmp
* 参  数: fileName -- 转换之后的文件名
* 功  能: 将转换后的图像信息写入到fileName文件中
*/
bool writeBmp(char *fileName)
{
FILE *fp = fopen(fileName,"wb");   //以二进制写方式打开
if(NULL == fp)
{
cout<<"File is opened failure!"<<endl;
return FALSE;
}
//写入数据
fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
fwrite(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,fp);
fwrite(pColorTable,sizeof(RGBQUAD),256,fp);
fwrite(pGrayData,sizeof(unsigned char),bmpInfoHeader.biSizeImage,fp);
fclose(fp);
//释放内存空间
delete []pColorTable;
delete []pBmpData;
delete []pGrayData;
return TRUE;
}
/**
* 函数名: work
* 功  能: 主要处理步骤
*/
void work()
{
char readFileName[] = "test1.bmp";
if(!readBmp(readFileName))
cout<<"The function of readBmp error!"<<endl;
convert();
char writeFileName[] = "gray.bmp";
if(!writeBmp(writeFileName))
cout<<"The function of writebmp error!"<<endl;
cout<<"convert success!"<<endl;

}
int main()
{
work();
return 0;
}

将24位真彩色图转换为8位灰度图片相关推荐

  1. 将32位浮点音频转换为16位

    (注:只改变量化位数,并不改变采样率和声道数等信息)  弄了一个下午加一个早上,终于算是弄完了,效果非常不错,音质无损失,之前一直用ffmpeg做重采样处理,但是一直是各种艰辛,各种奔溃,很无语,最后 ...

  2. labelme 标注生成24位深度图像转换为8位

    新版本的 labelme 标注完成图像后,将 json 文件转换为图像时已经转换为 8 通道图像,如下图所示: 最近在看别人程序时发现经过图像标注生成的 label 一片黑,且图像深度为 24 位,如 ...

  3. 24位真彩色图像转换为16位高彩色图像的实现方法及效果改进

    本篇博文来自博主Imageshop,打赏或想要查阅更多内容可以移步至Imageshop. 转载自:https://www.cnblogs.com/Imageshop/p/3453569.html   ...

  4. 使用GDI+将24位真彩色图像转换为8位灰度图像

    在图像处理中,我们经常需要将真彩色图像转换为黑白图像.黑白图像即为灰度图,即只有纯黑,纯白两种颜色. 计算机中的图像大致可以分为两类:位图(Bitmap)和矢量图(Metafile).位图可以视为一个 ...

  5. 64位数值强制转换为32位

    在程序中经常看到将int64的类型强制转换为int32类型,转换前后发生什么样的变化呢? int64 a=xxxxx; int32 b=0; b=a; b=a的过程几完成了强制转换. 其实强制转换的过 ...

  6. python字符串转64位数字_python-将String转换为64位整数映射字符以自定义两位值映射...

    您将4个不同"数字"的字符串解释为数字,因此以4为基数.如果您有一串实际数字,范围为0-3,则可以让int()真正快速地生成一个整数. def seq_to_int(seq, _m ...

  7. 将16位的深度图转换为8位深度图

    原理 一张16位的图像,意思是一张图像的每个像素点的像素值都由16位的二进制数表示,每个像素点的颜色有 2^16 = 65536 种可能. 也就是说,图像的颜色区间被划分成了2^16 = 65536份 ...

  8. 24位真彩和32位真彩

    24位真彩模式,每通道宽为一个字节,共计三个通道,也就是说每像素占3字节. inline void Plot_Pixel_24(int x, int y,                        ...

  9. 24位深的bmp图片转换为16位深RGB565格式的bmp图片源码

    /**24位深的bmp图片转换为16位深RGB565格式的bmp图片**/ #include <iostream> #include <stdio.h> #include &l ...

最新文章

  1. 不要重复发明轮子:C++重用的5重境界
  2. OpenCV图像缩放函数resize()的使用
  3. Spring MVC 返回NULL时客户端用$.getJSON的问题
  4. 【ElasticSearch】Es 缓存
  5. Jenkins远程调度Shell命令
  6. ES6 iterator 迭代器
  7. 爆款综艺也总火不过三季?谁来背锅?
  8. 机器人周志_关于机器人的日记
  9. 网易云信七鱼市场总监姜菡钰:实战解读增长黑客在B端业务的运用
  10. 流行音乐表明我们的注意力越来越短
  11. Python ln_LN型芯型联轴器
  12. libuv访问mysql_浅析libuv源码-编译启动
  13. 抖音seo源码,抖音矩阵,抖音seo系统,抖音搜索排名
  14. jQuary中delegate()函数的作用
  15. 用html+css实现小米官网的模拟
  16. org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.jt.mapper.UserM
  17. 办理充电宝移动电源GB/T35590-2017费用多少钱
  18. 先参与创业,再主导创业:给想创业的毕业生的一封信
  19. 上海朋友推荐科科过PMP备考三点心得
  20. 用hive解决数据的查找问题(影评案例)

热门文章

  1. 模型评估与验证(二)
  2. 如何保护SSL证书的私钥安全?
  3. 聊聊数据的分类和分级
  4. 比尔盖茨痛数离婚:我确实出轨犯下大错,爱泼斯坦的事早该听她的
  5. 微信支持手机温度监控;苹果、谷歌和微软扩大对无密码登录的支持;可在浏览器中运行Python应用的框架发布 | EA周报...
  6. 杜洋PCB设计视频教程笔记(陆续更新)
  7. Java中的数组缩减题目解答
  8. 判断浏览器系统是IOS还是PC还是android
  9. 水王争霸 SSL_1549
  10. jdk-7u7-linux-i586.tar.gz 和 jdk-7u51-windows-i586.exe 以及 CentOS6.8镜像下载