VC编程实现灰度图像与彩色图像的相互转换要点
图像灰度化方法总结及其VC实现

图像灰度化方法总结及其VC实现最近一段时间作者开始进行运动目标识别定位系统设计,本文以及后续的几篇文章都是从一个图像处理初学者的角度来总结目标检测定位过程中所应用到的各种常见的算法,尤其是解决算法实现过程中由于粗心大意或者C编程基本功不扎实所引起的各种问题。
本文主要对彩色图片灰度化的方法及其实现过程进行总结,最终给出实现的C代码。
在进行视频流目标识别与跟踪时,通常第一个步骤就是对采集到的彩色图像进行灰度化,这是因为黑白照片数据量小,相比彩照更易实现实时算法,另一方面黑白照片是由未处理的光线所形成的照片,因此从图像处理学角度来看,这种未经特殊滤光处理的图片所涵盖的信息更有价值。
目前,在图像处理过程中,最常用的彩色图片格式有RGB,HSV、YUV以及HLS三种。
以下分别对这三种格式的彩色图像进行灰度化实现。
1、RGB空间图像定义于RGB空间的彩色图,其每个像素点的色彩由R、G、B三个分量共同决定。
每个分量在内存所占的位数共同决定了图像深度,即每个像素点所占的字节数。
以常见的24深度彩色RGB图来说,其三个分量各占1个字节,这样每个分量可以取值为0~255,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围。
对这样一幅彩色图来说,其对应的灰度图则是只有8位的图像深度(可认为它是RGB三个分量相等),这也说明了灰度图图像处理所需的计算量确实要少。
不过需要注意的是,虽然丢失了一些颜色等级,但是从整幅图像的整体和局部的色彩以及亮度等级分布特征来看,灰度图描述与彩色图的描述是一致的。
对于RGB图像进行灰度化,通俗点说就是对图像的RGB三个分量进行加权平均得到最终的灰度值。
最常见的加权方法如下:1)Gray=B;Gray=G;Gray=R2)Gray=max(B+G+R)3)Gray=(B+G+R)/34)Gray= 0.072169B+ 0.715160G+ 0.212671R5)Gray= 0.11B+ 0.59G+ 0.3R这三种方法中,第一种为分量法,即用RGB三个分量的某一个分量作为该点的灰度值;第二种方法为最大值法,将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。
C#两种获取灰度图像的方法

C#两种获取灰度图像的方法第一种:在图像处理程序开发中,常会遇到将一幅彩色图像转换成灰度图像的情况,笔者在最近的一个项目中便遇到了这点。
经过一翻努力最终解决,想想有必要分享一下,于是便写下此文。
在本文中,将向各位读者介绍两种实现这一变换的方法,这也是笔者先后使用的两种方法。
本文的例子使用C#语言编写,使用的集成开发环境是Visual Studio 2005。
第一种,直接调用GetPixel/SetPixel方法。
我们都知道,图像在计算机中的存在形式是位图,也即一个矩形点阵,每一个点被称为一个像素。
在这种方法中,我们通过GDI+中提供的GetPixel方法来读取像素的颜色,并加以计算,然后再使用SetPixel方法将计算后的颜色值应用到相应的像素上去,这样便可以得到灰度图像。
上边提到的“计算”便是指得到灰度图像的计算,其公式是:r = (像素点的红色分量 + 像素点的绿色分量 + 像素点的蓝色分量) / 3最后得到的r便是需要应用到原像素点的值。
具体的编程实现也非常的简单,只需要遍历位图的每一个像素点,然后使用SetPixel方法将上边计算得到的值应用回去即可。
主要代码如下所示:Color currentColor;int r;Bitmap currentBitmap = new Bitmap(picBox.Image);Graphics g = Graphics.FromImage(currentBitmap);for (int w = 0; w < currentBitmap.Width; w++){for (int h = 0; h < currentBitmap.Height; h++){currentColor = currentBitmap.GetPixel(w, h);r = (currentColor.R + currentColor.G + currentColor.B) / 3;currentBitmap.SetPixel(w, h, Color.FromArgb(r, r, r));}}g.DrawImage(currentBitmap, 0, 0);picBox.Image = currentBitmap;g.Dispose();以上代码非常简单,不需要做太多的解释。
cvtcolor 函数 原理 c++ opencv 背后代码

cvtColor是OpenCV 中的一个非常有用的函数,用于将图像从一种颜色空间转换到另一种颜色空间。
在C++ 中,它的基本语法如下:
cpp复制代码
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0);
其中:
•src是输入图像,它是一个多通道的图像。
•dst是输出图像,它的类型和通道数由code参数决定。
•code是转换类型,比如CV_BGR2GRAY,CV_BGR2HSV等。
•dstCn是输出图像的通道数,如果为0,则根据code参数确定通道数。
下面我们深入到其背后代码的工作原理:
cvtColor的工作方式是通过使用查找表(LUT)来实现的。
查找表是一个预先计算好的数组,用于快速查找像素的转换值。
这使得颜色空间转换可以在常数时间内完成,大大提高了效率。
对于每个像素,我们可以通过查找表找到其在新颜色空间中的值。
例如,如果我们正在将一个RGB 图像转换为灰度图像,那么对于每个RGB 值,我们可以在查找表中查找其对应的灰度值。
然后,我们用这个灰度值替换原来的RGB 值。
这种方法的优点是速度快,但也有一个缺点:它需要预先计算查找表,这可能会占用大量的内存。
然而,对于大多数应用来说,这是可以接受的。
请注意,OpenCV 提供了许多内置的颜色空间转换代码,如CV_BGR2GRAY(从BGR 颜色空间到灰度颜色空间),CV_BGR2HSV(从BGR 颜色空间到HSV 颜色空间)等。
用户也可以定义自己的颜色空间转换代码。
color_gray2bgr 原理

color_gray2bgr 原理color_gray2bgr是一个用于将灰度图像转换为彩色图像的函数。
在计算机视觉和图像处理中,灰度图像是一种只有灰度值而没有颜色的图像,每个像素点的灰度值表示了该像素的亮度。
而彩色图像则具有多个通道,每个通道对应不同的颜色分量,例如红、绿、蓝(RGB)。
在很多应用中,我们需要将灰度图像转换为彩色图像,以提供更多的信息和细节。
color_gray2bgr函数正是为了满足这个需求而设计的。
它的原理是通过将灰度图像的灰度值赋给彩色图像的每个颜色通道,从而生成一个具有相同亮度但是彩色的图像。
具体而言,color_gray2bgr函数首先创建一个与灰度图像相同大小的彩色图像。
然后,它遍历灰度图像中的每个像素,将该像素的灰度值分别赋给彩色图像的红、绿和蓝通道。
这样,我们就得到了一个彩色图像,其中的每个像素都具有与原灰度图像相同的亮度,但是拥有不同的颜色。
通过这种方式,color_gray2bgr函数能够将灰度图像转换为彩色图像,从而提供更多的信息和细节。
这对于一些图像处理任务非常有用,例如目标检测和图像分割。
通过将灰度图像转换为彩色图像,我们可以更好地区分不同的物体和区域,从而提高算法的准确性和效果。
需要注意的是,color_gray2bgr函数只是一种简单的转换方式,它并不能从灰度图像中恢复出原始的彩色信息。
因为在灰度图像中,不同的颜色信息已经被丢失,只剩下了亮度信息。
所以,通过简单地将灰度值赋给彩色通道,并不能还原出原始的彩色图像。
在实际应用中,如果我们需要从灰度图像中恢复出原始的彩色信息,就需要借助其他的方法和技术。
例如,可以通过图像分析和机器学习的方法,从其他信息中推断出原始的彩色信息。
这是一个非常复杂的问题,需要深入的研究和专业的知识。
color_gray2bgr是一个用于将灰度图像转换为彩色图像的函数。
它通过将灰度值赋给彩色通道,生成一个具有相同亮度但是彩色的图像。
彩色图像与灰度图像之间的转换

彩⾊图像与灰度图像之间的转换⼀.彩⾊图像简介在RGB⾊彩空间,图像深度与⾊彩的映射关系主要有真彩⾊、伪彩⾊和调配⾊。
真彩⾊是指在组成⼀幅彩⾊图像的每个像素值中,有R,G,B三个基⾊分量,每个基⾊分量直接决定显⽰设备的基⾊强度,这样产⽣的彩⾊称为真彩⾊,是真实的原图彩⾊。
伪彩⾊图像的每个像素值实际上是⼀个索引值或代码,该代码值作为⾊彩查找表CLUT中某⼀项的⼊⼝地址,根据该地址可查找出包含实际R,G,B的强度值。
这种⽤查找映射的⽅法产⽣的⾊彩称为伪彩⾊。
⾊彩查找表CLUT是⼀个事先做好的表,表项⼊⼝地址也称为索引号。
彩⾊图像本⾝的像素数值和⾊彩查找表的索引号有⼀种变换关系,这种关系可以是系统定义的,也可以是⽤户⾃⼰定义的变换关系。
使⽤查找得到的数值显⽰的彩⾊是真的,可⼜不是图像本⾝的颜⾊,因为其没有完全反映原图的彩⾊,所以称其为伪彩⾊。
调配⾊的获取是通过每个像素点的R,G,B分量分别作为单独的索引值进⾏变换,经相应的⾊彩查找表找出各⾃的基⾊强度,⽤变换后的R,G,B强度值产⽣⾊彩。
⼆.灰度图像简介灰度是描述灰度图像内容的最直接的视觉特征。
它指⿊⽩图像中点的颜⾊深度,范围⼀般从0到255,⽩⾊为255,⿊⾊为0,故⿊⽩图像也称灰度图像。
灰度图像矩阵元素的取值通常为[0,255],因此其数据类型⼀般为8位⽆符号整数,这就是⼈们通常所说的256级灰度。
三.彩⾊图像转化为灰度图像彩⾊图像转换为灰度图像时,需要计算图像中每个像素有效的亮度值,其计算公式为:Y = 0.3R + 0.59G + 0.11B代码如下:clear all;close all;I = imread('lenna.png');[M N H] = size(I);I2 = zeros(M, N);for x = 1 : Mfor y = 1 : NA = double([I(x, y, 1) I(x, y, 2) I(x, y, 3)]);B = [0.3; 0.59; 0.11];[gray] = A * B; % 计算灰度值I2(x, y) = gray;endendimshow(uint8(I2));四.灰度图像转换为彩⾊图像将灰度图像转换为彩⾊图像,称为灰度图像的伪彩⾊处理。
cvcvtcolor函数

cvcvtcolor函数cvCvtColor函数是OpenCV中的一个非常重要的函数,它能够实现将视频图像数据中的RGB颜色空间转换到其他格式,也就是彩色图像可以由它转换成灰度图像,或者灰度图像可以转换成彩色图像。
1. cvCvtColor函数的作用cvCvtColor函数的作用是实现图像的颜色空间变换,因此它通常被用于彩色图像转换为灰度图像和灰度图像转换为彩色图像。
它的应用非常广泛,包括图像处理、计算机视觉等。
2. cvCvtColor函数的参数cvCvtColor函数定义格式为:cvCvtColor( src, dst, code ),其中src代表原图像,dst代表目标图像,code代表转换类型:(1)CV_BGR2GRAY: BGR图像转换到灰度图像;(2)CV_RGB2GRAY: RGB图像转换到灰度图像;(3)CV_GRAY2BGR:灰度图转换到BGR图像;(4)CV_GRAY2RGB:灰度图转换到RGB图像。
3. cvCvtColor函数的应用(1)数字图像处理:在数字图像处理中,OpenCV中提供了cvCvtColor函数,可以将彩色图像数据转换为其他格式或者灰度图像转换为彩色图像,以便对图像进行更进一步的处理;(2)计算机视觉:cvCvtColor函数也可以用于计算机视觉,可以将彩色图像数据转换为灰度图像或者灰度图像转换为彩色图像,便于进一步提取图像特征信息再使用。
4. cvCvtColor函数的优点(1)cvCvtColor函数有效简化了图像转换操作,可以大大提高图像处理效率;(2)它提供了多种不同的颜色空间转换,灵活性强;(3)转换的结果一般来说满足客观要求;(4)它可以让图像数据对更多的开发平台都可以被有效利用。
灰度转伪彩原理

灰度转伪彩原理灰度转伪彩原理是数字图像处理中常用的一种技术,它可以将灰度图像转换为伪彩色图像,使得图像更加直观、易于观察和分析。
本文将介绍灰度转伪彩的原理及其应用。
一、灰度图像与伪彩色图像的区别灰度图像是指每个像素点的颜色只有黑、白和灰色,它的颜色信息只有一个通道,即灰度值。
而伪彩色图像是将灰度图像的灰度值映射到伪彩色表中,通过伪彩色表来表示不同的灰度值范围对应的颜色,从而使图像呈现出多种颜色,增加了图像的信息量。
二、灰度转伪彩的原理灰度转伪彩的原理主要包括灰度映射和伪彩色表的生成两个步骤。
1. 灰度映射灰度映射是将灰度图像中的灰度值映射到伪彩色表上的过程。
常用的灰度映射方法有线性映射、对数映射、幂次映射等。
其中,线性映射是最常用的方法,它通过线性函数将灰度值映射到伪彩色表上,从而实现灰度图像到伪彩色图像的转换。
2. 伪彩色表的生成伪彩色表是指将灰度图像中的不同灰度值映射到不同的颜色上,形成伪彩色图像的颜色表。
伪彩色表通常由多种颜色组成,每种颜色代表一定范围的灰度值。
生成伪彩色表的方法有很多种,常用的有线性映射法、对数映射法、直方图均衡化等。
三、灰度转伪彩的应用灰度转伪彩技术在医学影像、地质勘探、红外图像处理等领域有着广泛的应用。
1. 医学影像在医学影像中,灰度转伪彩技术可以将CT、MRI等灰度图像转换为伪彩色图像,使得医生在观察病灶时更加直观和准确。
例如,将肿瘤映射为红色、健康组织映射为绿色,可以帮助医生更好地诊断和治疗疾病。
2. 地质勘探在地质勘探中,利用灰度转伪彩技术可以将地质图像中的地质信息以不同的颜色显示出来,帮助地质学家更好地分析地质结构和地质特征。
例如,将不同类型的矿石映射为不同的颜色,可以帮助地质学家找到矿产资源。
3. 红外图像处理在红外图像处理中,灰度转伪彩技术可以将红外图像中的温度信息以不同的颜色呈现出来,使得人眼可以直观地观察到温度分布的差异。
例如,在建筑物的热成像检测中,将高温区域映射为红色,低温区域映射为蓝色,可以帮助工程师及时发现隐患。
图像打开,另存为,转为灰度图像(利用cimage方法实现)

CImage类的介绍与使用程序代码下载处:/source/2098910下载处:/wangleitongxing/blog/item/9063b03e5e20f3c97c1e71c8.htmlVisual C++的CBitmap类和静态图片控件的功能是比较弱的,它只能显示出在资源中的图标、位图、光标以及图元文件的内容,而不像VB中的Image控件可以显示出绝大多数的外部图像文件(BMP、GIF、JPEG等)。
因此,想要在对话框或其他窗口中显示外部图像文件则只能借助于第三方提供的控件或代码。
现在,MFC和ATL共享的新类CImage为图像处理提供了许多相应的方法,这使得Visual C++在图像方面的缺憾一去不复返了。
CImage类概述CImage是MFC和ATL共享的新类,它能从外部磁盘中调入一个JPEG、GIF、BMP和PNG格式的图像文件加以显示,而且这些文件格式可以相互转换。
由于CImage在不同的Windows 操作系统中其某些性能是不一样的,因此在使用时要特别注意。
例如,CImage::PlgBlt和CImage::MaskBlt只能在Windows NT 4.0 或更高版本中使用,但不能运行在Windows 95/98 应用程序中。
CImage::AlphaBlend和CImage::TransparentBlt也只能在Windows 2000/98或其更高版本中使用。
即使在Windows 2000运行程序还必须将stdafx.h文件中的WINVER和_WIN32_WINNT的预定义修改成0x0500才能正常使用。
CImage封装了DIB(设备无关位图)的功能,因而可以让我们能够处理每个位图像素。
它具有下列最酷特性:1、AlphaBlend支持像素级的颜色混合,从而实现透明和半透明的效果。
2、PlgBlt能使一个矩形区域的位图映射到一个平行四边形区域中,而且还可能使用位屏蔽操作。
3、TransparentBlt在目标区域中产生透明图像,SetTransparentColor用来设置某种颜色是透明色。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VC编程实现灰度图像与彩色图像的相互转换PhotoShop的图像处理功能很强,其中有一个功能是将灰度图像转换为彩色图像,数字图像处理中,也经常要遇到灰度图像与彩色图像相互转换的问题,如何自己解决这个问题,值得大家探讨,现将我解决这类问题的方法陈述如下:工程应用中经常要遇到需要把彩色图像到灰度图像的变换的问题,采集卡过来的图像为彩色图像,为加快处理速度,要把彩色图像转换为黑白图象,这个问题比较好解决,一般情况下彩色图像每个像素用三个字节表示,每个字节对应着R、G、B分量的亮度(红、绿、蓝),转换后的黑白图像的一个像素用一个字节表示该点的灰度值,它的值在0~255之间,数值越大,该点越白,既越亮,越小则越黑。
转换公式为Gray(i,j)=0.11*R(i,j)+0.59*G(i,j)+0.3*B(i,j),其中Gray(i,j)为转换后的黑白图像在(i,j)点处的灰度值,我们可以观察该式,其中绿色所占的比重最大,所以转换时可以直接使用G值作为转换后的灰度。
至于灰度图像转换为彩色图像,技术上称为灰度图像的伪彩色处理,这是一种视觉效果明显而技术又不是很复杂的图像增强技术。
灰度图像中,如果相邻像素点的灰度相差不大,但包含了丰富的信息的话,人眼则无法从图像中提取相应的信息,因为人眼分辨灰度的能力很差,一般只有几十个数量级,但是人眼对彩色信号的分辨率却很强,这样将黑白图像转换为彩色图像人眼可以提取更多的信息量。
在转换过程中,经常采用的技术是灰度级-彩色变换,意思就是对黑白图像上的每一个像素点,取得该点的灰度值并送入三个通道经过实施不同的变换,产生相应的R、G、B的亮度值,即所求彩色图像对应像素点的彩色值,具体变换公式很多,我采用的是最常用的一种,变换曲线图如下:上图中,三个图分别代表了三个变换通道,R、G、B指的是变换后对应点的R、G、B分量值,L指的是各个分量的最大值为255,G(x,y)为相应点的灰度值。
理论上就这些,下面是我用VC实现的源代码,图一为我的灰度位图,图二为伪彩色处理后的结果图。
我这个实现函数中是如何得到灰度位图的数据的就不多讲了,有兴趣的朋友可参考我在天极网上九月十号发表的《VC灰度位图处理》一文,那里应该讲的很清楚了。
需要读者注意的是彩色图像中每个象素中的三个字节分别代表的分量,第一个字节为B,第二个为G值、最后一个为R值,这个顺序不要搞错了。
代码实现如下:void CDibView::OnMenuchange() file://图像转换实现函数{// TODO: Add your command handler code hereHANDLE data1handle;LPBITMAPINFOHEADER lpBi;BITMAPINFO *m_pBMI;CDibDoc *pDoc=GetDocument();HDIB hdib;unsigned char *hData;unsigned char *data;hdib=pDoc->GetHDIB();//得到位图数据的句柄,其中包含图像信息头BeginWaitCursor();lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)hdib);hData=(unsigned char*)FindDIBBits((LPSTR)lpBi);m_pBMI=new BITMAPINFO;//生成彩色图像的信息头m_pBMI->bmiHeader.biBitCount=24;m_pBMI->bmiHeader.biClrImportant=0;m_pBMI->bmiHeader.biClrUsed=0;m_pBMI->bmiHeader.biCompression=BI_RGB;m_pBMI->bmiHeader.biHeight=lpBi->biHeight;m_pBMI->bmiHeader.biWidth=lpBi->biWidth;m_pBMI->bmiHeader.biPlanes=1;m_pBMI->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);m_pBMI->bmiHeader.biXPelsPerMeter=0;m_pBMI->bmiHeader.biYPelsPerMeter=0;m_pBMI->bmiHeader.biSizeImage=WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight*3;file://data=hData;int R,G,B,i,j;data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight*3);file://生成存储彩色图象数据的缓冲区data=(unsigned char*)GlobalLock((HGLOBAL)data1handle);for(i=0;i biHeight;i++)//实现灰度到彩色变换for(j=0;jbiWidth*8);j++){if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=64){R=0;G=(int)4*(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));B=255;}if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>64&& *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=128){R=0;G=255;B=(int)4*(128-*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));}if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>128&& *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=192){R=(int)4*(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)-128);G=255;B=0;}if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>192&& *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=255){R=255;G=(int)4*(255-*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));B=0;}file://将生成的R、G、B分量存入目标缓冲区*(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3)=B;*(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3+1)=G;*(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3+2)=R;}GlobalUnlock((HGLOBAL)hdib);GlobalUnlock(data1handle);EndWaitCursor();CClientDC pDC(this);file://显示真彩色图像StretchDIBits(pDC.GetSafeHdc(),0,0,lpBi->biWidth,lpBi->biHeight,0,0,lpBi->biWidth, lpBi->biHeight,data,m_pBMI,DIB_RGB_COLORS,SRCCOPY);delete m_pBMI;}VC++ 灰度位图处理图像处理技术已经渗透到人类生活的各个领域并得到越来越多的应用,图像处理所涉及的图像格式有很多种,如TIF、JEMP、BMP等等,工程应用中经常要处理256级的灰度BMP图像,如通过黑白采集卡采集得到的图像。
BMP灰度图像作为Windows环境下主要的图像格式之一,以其格式简单,适应性强而倍受欢迎。
在进行图像处理时,操作图像中的像素值就要得到图像阵列;经过处理后的图像的像素值存储起来;显示图像时要正确实现调色板,结合这些问题,文章针对性的给出了操作灰度BMP图像时的部分函数实现代码及注释。
一、BMP位图操作BMP位图包括位图文件头结构BITMAPFILEHEADER、位图信息头结构BITMAPINFOHEADER、位图颜色表RGBQUAD和位图像素数据四部分。
处理位图时要根据文件的这些结构得到位图文件大小、位图的宽、高、实现调色板、得到位图像素值等等。
对于256级灰度图像每个像素用8bit表示颜色的索引值,这里要注意的一点是在BMP位图中,位图的每行像素值要填充到一个四字节边界,即位图每行所占的存储长度为四字节的倍数,不足时将多余位用0填充。
在处理图像应用程序的文档类(CdibDoc.h)中声明如下宏及公有变量:#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)//计算图像每行象素所占的字节数目HANDLE m_hDIB;//存放位图数据的句柄CPalette* m_palDIB;//指向调色板Cpalette类的指针CSize m_sizeDoc; file://初始化视图的尺寸1、读取灰度BMP位图根据BMP位图文件的结构,操作BMP位图文件读入数据,重载了文挡类的OnOpenDocument函数如下:BOOL CDibDoc::OnOpenDocument(LPCTSTR lpszPathName){CFile file;CFileException fe;if (!file.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite, &fe)){AfxMessageBox("文件打不开");return FALSE;}//打开文件DeleteContents();//删除文挡BeginWaitCursor();BITMAPFILEHEADER bmfHeader;//定义位图文件头结构DWORD dwBitsSize;HANDLE hDIB;LPSTR pDIB;BITMAPINFOHEADER *bmhdr;//指向位图信息头结构的指针dwBitsSize = file.GetLength();//得到文件长度if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) !=sizeof(bmfHeader))return FALSE;if (bmfHeader.bfType != 0x4d42) file://检查是否为BMP文件return FALSE;hDIB=(HANDLE) ::GlobalAlloc(GMEM_MOVEABLE |GMEM_ZEROINIT, dwBitsSize);file://申请缓冲区if (hDIB == 0){return FALSE;}pDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);file://得到申请的缓冲区的指针if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=dwBitsSize - sizeof(BITMAPFILEHEADER) ){::GlobalUnlock((HGLOBAL)hDIB);hDIB=NULL;return FALSE;}//读数据,包括位图信息、位图颜色表、图像像素的灰度值bmhdr=(BITMAPINFOHEADER*)pDIB;//为指向位图信息头结构的指针付值::GlobalUnlock((HGLOBAL)hDIB);if ((*bmhdr).biBitCount!=8) file://验证是否为8bit位图return FALSE;m_hDIB=hDIB;InitDIBData();file://自定义函数,根据读入的数据得到位图的宽、高、颜色表file:// 来得到初始化视的尺寸、生成调色板EndWaitCursor();SetPathName(lpszPathName);//设置存储路径SetModifiedFlag(FALSE); // 设置文件修改标志为FALSEreturn TRUE;}2、灰度位图数据的存储为了将图像处理后所得到的像素值保存起来,重载了文档类的OnSaveDocument函数,其具体实现如下:BOOL CDibDoc::OnSaveDocument(LPCTSTR lpszPathName){CFile file;CFileException fe;BITMAPFILEHEADER bmfHdr; // 位图文件头结构LPBITMAPINFOHEADER lpBI; file://指向位图信息结构的指针DWORD dwDIBSize;if (!file.Open(lpszPathName, CFile::modeCreate |CFile::modeReadWrite | CFile::shareExclusive, &fe)){AfxMessageBox("文件打不开");}//打开文件BOOL bSuccess = FALSE;BeginWaitCursor();lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) m_hDIB);if (lpBI == NULL)return FALSE;dwDIBSize = *(LPDWORD)lpBI + 256*sizeof(RGBQUAD);// Partial CalculationDWORD dwBmBitsSize;//BMP文件信息结构所占的字节数dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) *lpBI->biHei ght;// 存储时位图所有像素所占的总字节数dwDIBSize += dwBmBitsSize;lpBI->biSizeImage = dwBmBitsSize; // 位图所有像素所占的总字节数file://以下五句为文件头结构填充值bmfHdr.bfType =0x4d42; // 文件为"BMP"类型bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);//文件总长度bmfHdr.bfReserved1 = 0;bmfHdr.bfReserved2 = 0;bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize+ 256*sizeof(RGBQUAD);file://位图数据距问件头的偏移量file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));//写文件头file.WriteHuge(lpBI, dwDIBSize);file://将位图信息(信息头结构、颜色表、像素数据)写入文件::GlobalUnlock((HGLOBAL) m_hDIB);EndWaitCursor();SetModifiedFlag(FALSE); // back to unmodifiedreturn TRUE;}二、调色板的操作灰度图像要正确显示,必须实现逻辑调色板和系统调色板,通过在主框架类中处理Windows定义的消息WM_QUERYNEWPALETTE 、WM_PALETTECHANGED及视图类中处理自定义消息WM_DOREA LIZE(该消息在主框架窗口定义如下:#define WM_REALIZEPAL (WM_USER+100))来实现调色板的操作。