非常感谢Imageshop的指正,代码有修改,主要是:

  1. 计算8位位图像素位使用了更高效的整点运算;
  2. 去除多余的变量检测。

求网友们支招:在32位位图中有Alpha值,在转换成8位灰阶位图的时候可以直接省略吗?

在《我的第一个MFC小项目(3)之 位图转换》中,有关于将24位的彩色位图转换为8位的灰阶位图,发散一下就很容易可以得到32位位图彩图转换为8位的灰阶位图,看图:

32位位图多出一个Alpha字节,用来描述图片的透明度,根据这一特性,可以将Alpha特意忽略,然后将紧跟其后的RGB按照《我的第一个MFC小项目(3)之 位图转换》中24位位图转8位灰阶位图的方法就可以很轻易地达到我们的目的。这一次的位图转换接口我优化了一下,下面给出代码

void Convertto8Bit(LPWSTR lpSrcFileName,LPWSTR lpDestFileName)
{HANDLE hFile;                  //文件句柄DWORD dwWritten;          //记录以写入的字节数hFile   =   CreateFile(lpSrcFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);BITMAPFILEHEADER  bmfh;                    //文件头ReadFile(hFile,&bmfh,sizeof(BITMAPFILEHEADER),&dwWritten,NULL);BITMAPINFOHEADER   bmif;                    //信息头ReadFile(hFile,&bmif,40,&dwWritten,NULL);  DWORD   dwSizeImage;                        //源文件像素位大小dwSizeImage   =                                  //获取 像素位 的大小,分配空间bmif.biSizeImage;BYTE * pBits   =   new BYTE[dwSizeImage];   ReadFile(hFile,pBits,dwSizeImage,&dwWritten,NULL);::CloseHandle(hFile);long  lSrcWidth = bmif.biWidth;                   //原图长与宽long lSrcHeight = bmif.biHeight;long lLineBytes;                            //原图每行总字节数long lScanWidth;                      //转换为8位图之后的宽度,必须是大于原图且为4的倍数lLineBytes = (lSrcWidth*4);          /*if(lLineBytes<lSrcWidth*4)                 //在这里转换需要比原图每行总字节数大lLineBytes += 4;*/lScanWidth = (lSrcWidth/4)*4;           //8位位图的宽度必须为4的倍数,在这里转换需要比原图宽度大if(lScanWidth<lSrcWidth)lSrcWidth += 4;DWORD dwSizeNewImage = lSrcWidth * lSrcHeight + 2;           //为什么要预留两位呢BYTE * bits = new BYTE[dwSizeNewImage];for(int i=0; i<lSrcHeight; i++){for(int j=0; j<lSrcWidth; j++){BYTE color[3];                        //对应RGB的红绿蓝值DWORD dwColorTemp;          //Y值,RGB转换为Y之后的值Y=0.299*R+0.587*G+0.114*Bfor(int s=0;s<3; s++)          //一个RGB对应一个Y值color[s]=pBits[i*lLineBytes+j*4+s+1];/*dwColorTemp=unsigned int(color[2]*0.299+color[1]*0.587+color[0]*0.114);     *///换成更高效的计算,确实快很多dwColorTemp=unsigned int(color[2]*30+color[1]*59+color[0]*11+50)/100;     //多余的变量检测/*if(dwColorTemp>255)dwColorTemp = 255;if(dwColorTemp<0)dwColorTemp = 0;*/bits[i*lScanWidth+j]=(unsigned char)dwColorTemp;}}bits[dwSizeNewImage-1] = 0;bits[dwSizeNewImage-2] = 0;RGBQUAD   *rgbQuad   =   new   RGBQUAD[256];   //颜色表for(int i=0;i<256;i++)   {   rgbQuad[i].rgbBlue   =   i;     rgbQuad[i].rgbGreen   =   i;     rgbQuad[i].rgbRed   =   i;     rgbQuad[i].rgbReserved   =   0;     }   //完善8位位图的文件头和信息头字段bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) +sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD);                //颜色表有256个bmfh.bfReserved1 = 0;bmfh.bfReserved2 = 0;bmfh.bfSize = bmfh.bfOffBits + dwSizeNewImage;          //size in byte of the filebmif.biBitCount = 8;                                                         //信息头中bitcounts改为8bmif.biSizeImage =  dwSizeNewImage;//写入转换后得到的8位位图hFile=CreateFile(lpDestFileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);::WriteFile(hFile,&bmfh,sizeof(BITMAPFILEHEADER),&dwWritten,NULL);::WriteFile(hFile,&bmif,sizeof(BITMAPINFOHEADER),&dwWritten,NULL);::WriteFile(hFile,rgbQuad,256*sizeof(RGBQUAD),&dwWritten,NULL);::WriteFile(hFile,bits,dwSizeNewImage,&dwWritten,NULL);::CloseHandle(hFile);
}

换汤不换药的。另外在这里问问大牛们,用MFC做图像处理的工程,是不是最好用单文档或者单文档之类的框架?

传送门:

我的第一个MFC小项目(3)之 位图转换

捣乱小子 2011-12-20

ps:欢迎讨论

我的第一个MFC小项目(4)之 位图转换(续)相关推荐

  1. python+opencv别踩白块儿游戏辅助,一天一个opencv小项目(已开源)

    python+opencv别踩白块儿游戏辅助,一天一个opencv小项目(已开源) 见链接

  2. 我的第一个JDBC小项目

    我的第一个JDBC小项目 引言:以下都是个人学习中的一些总结,本人能力有限,其中存在很多错误与不足,还请阅读者斧正.!并非教程!!并非教程!!并非教程! JDBC是Java DataBase Conn ...

  3. 安卓入门系列-09一个实战小项目(备忘录Memo)

    一个简单的安卓平台下的备忘录 背景 之前已经介绍了不少的控件(TextView和ListView等等)以及开发中最常见的组件(Activity)(Service的权重在我心中没有Activity重要, ...

  4. 将一个项目中的图片存到另一个项目中_复盘一个Smart200小项目(2)

    这一部分回顾一下确认项目功能需求的过程. 硬件系统选择: 第一阶段,陆陆续续在微信和电话上扯了大约一个周,确定了采用高级语言开发上位机的方案,准备开始确定采用什么PLC和触摸屏了,哥们说客户对使用什么 ...

  5. python秒表项目_第一个Python小项目——秒表

    一.项目描述: 前言: 这只是我今天试着写的一个小项目,这个项目我发在博客上只是为了便于保存,日后自己看起来方便,所以很多地方没有写注释,如果大家有什么想法,欢迎给我留言. 项目名称: 简易秒表 开发 ...

  6. 我写了一个Python小项目

    最近我写了一个 Python 练手小项目,它是一个 PC 桌面版的便签程序,很简陋.写这个小项目是为了熟悉一下用 Python 进行一个完整的项目开发,进一步熟练 Python 的使用. 界面是这样的 ...

  7. vue3实现一个抽奖小项目

    前言 在公司年会期间我做了个抽奖小项目,我把它分享出来,有用得着的可以看下. 浏览链接:http://xisite.top/original/luckDraw/index.html 项目链接:http ...

  8. java 台球_Java入门和一个台球小项目

    今天是入门学习Java的第二天,从今天起就算是正式地接触到了java语言编写的内容,以下是对于今天学习内容的一个梳理. 1. Java的核心优势是跨平台/可移植性. 其他特性:安全性,面向对象,简单性 ...

  9. 【MFC】创建第一个MFC界面项目

    00. 目录 文章目录 00. 目录 01. 概述 02. 使用项目模板创建项目 03. 运行结果 04. 附录 01. 概述 要创建MFC应用程序,可以使用向导来自定义的项目.也可以从头创建应用程序 ...

最新文章

  1. Android中有关数据库SQLite的介绍
  2. Build gradle : Could not find method packagingOptions() for arguments root Project “fasterDev”
  3. Windows核心编程 第八章 用户方式中线程的同步(上)
  4. 【科普】STP生成树协议
  5. 基于netty的微服务网关_基于Rx-netty和Karyon2的云就绪微服务
  6. c oracle实体模型,ADO.NET实体数据模型详细介绍
  7. mysql完成未完成_MYSQL SQL模式 (未完成)
  8. 模板---使用el选项指定模板/使用template选项指定内联模板/使用template选项指定独立模板/使用render选项指定要挂载的模板
  9. 10截图时屏幕变大_最全的MAC端截图工具推荐,寻找适合自己的截图工具
  10. libxml2如何配合php使用,libxml2实现xml文档的节点的修改
  11. 阿里云的工程师要被祭天了?
  12. matlab在同一窗口中画多个三维图像
  13. 【Python小程序】第2讲:如何将TXT文件转换成CSV文件?
  14. 【思路】2021年第十四届“认证杯“数学中国数学建模国际赛(小美赛)思路
  15. python 网格搜索_Python机器学习:6.4 通过网格搜索调参
  16. DP动态规划--乡村邮局问题-Post Office(POJ-1160)
  17. 蓝星实物微商城H5源码 附搭建教程
  18. Android 水瓶动画,贝塞尔Loading
  19. 指纹识别综述(4): 指纹匹配
  20. sqlserver和mysql定时同步_通过作业,定时同步两个数据库_sqlserver

热门文章

  1. mysql 核心笔记 逻辑符号 like
  2. 批处理定时执行任务_[Abaqus tips ] 分析任务的定时执行
  3. window安装python3后怎么用pyspark_pyspark:连接spark集群Windows环境搭建
  4. php fmod小数位数_PHP取余函数介绍MOD(x,y)与x%y
  5. hashmap put过程_阿里面试官:HashMap数据结构之道
  6. android 行居中,android自己定义换行居中CenterTextView
  7. mysql数据库 安装后 闪_MYSQL数据库Mysql数据库安装完成后需要进行的6个后续操作...
  8. faster rcnn resnet_张航、李沐等人提出ResNet最强改进版:性能提高3%,参数不增
  9. html的字母u代表什么意思,html元素 u 标签的使用方法及作用
  10. 中望CAD的引线标注格式怎么改_大神总结的CAD设计五个段位 快来看看你在哪个阶段...