ImageVerifierCode 换一换
格式:DOCX , 页数:26 ,大小:703.28KB ,
资源ID:4368950      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-4368950.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(24位真彩色转换为8位灰度图VC++代码.docx)为本站会员(b****3)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

24位真彩色转换为8位灰度图VC++代码.docx

1、24位真彩色转换为8位灰度图VC+代码24位真彩色转换为位灰度图 /#include BOOL BMP24to8(char *szSourceFile,char *szTargetFile); int main(int argc,char* argv)/调用这个函数直接把24位真彩色灰度化BOOL stat=BMP24to8(c:/source.bmp,c:/target.bmp);return 0;BOOL BMP24to8(char *szSourceFile,char *szTargetFile)HANDLE hSourceFile=INVALID_HANDLE_VALUE,hTarge

2、tFile=INVALID_HANDLE_VALUE;DWORD dwSourceSize=0,dwTargetSize=0;PBYTE pSource=NULL,pTarget=NULL;hSourceFile=CreateFile(szSourceFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if(hSourceFile=INVALID_HANDLE_VALUE) return FALSE;dwSourceSize=GetFileSize(hSourceFile,NULL);

3、pSource=(PBYTE)VirtualAlloc(NULL,dwSourceSize,MEM_COMMIT,PAGE_READWRITE);/分配空间失败或者文件太小(BMP文件不可能小于54个字节) if(pSource=NULL|dwSourceSizebfType!=0x4d42|pSourceInfoHeader-biBitCount!=24)CloseHandle(hSourceFile);VirtualFree(pSource,NULL,MEM_RELEASE);return FALSE;CloseHandle(hSourceFile);LONG nWidth=pSource

4、InfoHeader-biWidth;LONG nHeight=pSourceInfoHeader-biHeight;LONG nSourceWidth=nWidth*3;if(nSourceWidth%4) nSourceWidth=(nSourceWidth/4+1)*4;LONG nTargetWidth=nWidth;if(nTargetWidth%4) nTargetWidth=(nTargetWidth/4+1)*4;dwTargetSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256+

5、nHeight*nTargetWidth;pTarget=(PBYTE)VirtualAlloc(NULL,dwTargetSize,MEM_COMMIT,PAGE_READWRITE);memset(pTarget,0,dwTargetSize);if(pTarget=NULL)VirtualFree(pTarget,NULL,MEM_RELEASE);return FALSE;BITMAPFILEHEADER *pTargetFileHeader=(BITMAPFILEHEADER *)pTarget;BITMAPINFOHEADER *pTargetInfoHeader =(BITMAP

6、INFOHEADER *)(pTarget+sizeof(BITMAPFILEHEADER);pTargetFileHeader-bfType=pSourceFileHeader-bfType;pTargetFileHeader-bfSize=dwTargetSize;pTargetFileHeader-bfReserved1=0;pTargetFileHeader-bfReserved2=0;pTargetFileHeader-bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256;pTa

7、rgetInfoHeader-biBitCount=8;pTargetInfoHeader-biClrImportant=0;pTargetInfoHeader-biClrUsed=256;pTargetInfoHeader-biCompression=BI_RGB;pTargetInfoHeader-biHeight=pSourceInfoHeader-biHeight;pTargetInfoHeader-biPlanes=1;pTargetInfoHeader-biSize=sizeof(BITMAPINFOHEADER);pTargetInfoHeader-biSizeImage=nHe

8、ight*nTargetWidth;pTargetInfoHeader-biWidth=pSourceInfoHeader-biWidth;pTargetInfoHeader-biXPelsPerMeter=pSourceInfoHeader-biXPelsPerMeter;pTargetInfoHeader-biYPelsPerMeter=pSourceInfoHeader-biYPelsPerMeter;RGBQUAD *pRgb;for(int i=0;irgbBlue=i;pRgb-rgbGreen=i;pRgb-rgbRed=i;pRgb-rgbReserved=0;for (int

9、 m=0;mnHeight;m+)/转化真彩色图为灰度图for(int n=0;nbfOffBits+m*nTargetWidth+n =pSourcepSourceFileHeader-bfOffBits+m*nSourceWidth+n*3*0.114+pSourcepSourceFileHeader-bfOffBits+m*nSourceWidth+n*3+1*0.587+pSourcepSourceFileHeader-bfOffBits+m*nSourceWidth+n*3+2*0.299; hTargetFile = CreateFile(szTargetFile,GENERIC_

10、WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);BOOL stat=WriteFile(hTargetFile,pTarget,dwTargetSize,&dwTemp,NULL);CloseHandle(hTargetFile);VirtualFree(pSource,NULL,MEM_RELEASE);VirtualFree(pTarget,NULL,MEM_RELEASE);return stat;转化效果如下图 在GDI+中将24位真彩色图转换为灰度图(原理、C#调用指针) 在图像处理中,我们经

11、常需要将真彩色图像转换为黑白图像。严格的讲应该是灰度图,因为真正的黑白图像是二色,即只有纯黑,纯白二色。开始之前,我们先简单补充一下计算机中图像的表示原理。计算机中的图像大致可以分成两类:位图(Bitmap)和矢量图(Metafile)。 位图可以视为一个二维的网格,整个图像就是由很多个点组成的,点的个数等于位图的宽乘以高。每个点被称为一个像素点,每个像素点有确定的颜色,当很多个像素合在一起时就形成了一幅完整的图像。我们通常使用的图像大部分都是位图,如数码相机拍摄的照片,都是位图。因为位图可以完美的表示图像的细节,能较好的 还原图像的原景。但位图也有缺点:第一是体积比较大,所以人们开发了很多压

12、缩图像格式来储存位图图像,目前应用最广的是JPEG格式,在WEB上得到了广泛应用,另外还有GIF,PNG等 等。第二是位图在放大时,不可避免的会出现“锯齿”现象,这也由位图的本质特点决定的。所以在现实中,我们还需要使用到另一种图像格式:矢量图。同位图不 同,矢量图同位图的原理不同,矢量图是利用数学公式通过圆,线段等绘制出来的,所以不管如何放大都不会出现变形,但矢量图不能描述非常复杂的图像。所以矢量图都是用来描述图形图案,各种CAD软件等等都是使用矢量格式来保存文件的。在讲解颜色转换之前,我们要先对位图的颜色表示方式做一了解。位图中通常是用RGB三色方式来表示颜色的(位数很少时要使用调色板)。所

13、以每个像素采用不同的位数,就可以表示出不同数量的颜色。如下图所示:每像素的位数一个像素可分配到的颜色数量121 = 2222 = 4424 = 16828 = 25616216 = 65,53624224 = 16,777,216从中我们可以看出,当使用24位色(3个字节)时,我们可以得到1600多万种颜色,这已经非常丰富了,应该已接近人眼所能分辨的颜色了。现在计算机中使用最多的就是24位色,别外在GDI+中还有一种32位色,多出来的一个通道用来描述Alpha,即透明分量。24位色中3个字节分别用来描述R,G,B三种颜色分量,我们看到这其中是没有亮度分量的,这是因为在RGB表示方式中,亮度也是

14、直接可以从颜色分量中得到的,每一颜色分量值的范围都是从0到255,某一颜色分量的值越大,就表示这一分量的亮度值越高,所以255表示最亮,0表示最暗。那么一个真彩色像素点转换为灰度图时它的亮度值应该是多少呢,首先我们想到的平均值,即将R+G+B/3。但现实中我们使用的却是如下的公式:Y = 0.299R+0.587G+0.114B这个公式通常都被称为心理学灰度公式。这里面我们看到绿色分量所占比重最大。因为科学家发现使用上述公式进行转换时所得到的灰度图最接近人眼对灰度图的感觉。因为灰度图中颜色数量一共只有256种(1个字节),所以转换后的图像我们通常保存为8位格式而不是24位格式,这样比较节省空间

15、。而8位图像是使用调色板方式来保存颜色的。而不是直接保存颜色值。调色板中可以保存256颜色,所以可以正好可以将256种灰度颜色保存到调色版中。代码如下:using System;using System.Collections.Generic;using System.Text;using System.Drawing;using System.Drawing.Imaging;namespace ConsoleApplication2class Programunsafe static void Main(string args)Bitmap img = (Bitmap)Image.FromF

16、ile(E:/My Documents/My Pictures/cherry_blossom_1002.jpg);Bitmap bit = new Bitmap(img.Width,img.Height,PixelFormat.Format8bppIndexed);BitmapData data= img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);byte* bp = (byte*)data.Scan0.ToPointer();B

17、itmapData data2 =bit.LockBits(new Rectangle(0, 0, bit.Width, bit.Height), ImageLockMode.ReadWrite,PixelFormat.Format8bppIndexed);byte* bp2 = (byte*)data2.Scan0.ToPointer();for (int i = 0; i != data.Height; i+)for (int j = 0; j != data.Width; j+)/0.3R+0.59G+0.11Bfloat value = 0.11F * bpi * data.Strid

18、e + j * 3+ 0.59F * bpi * data.Stride + j * 3 + 1+ 0.3F * bpi * data.Stride + j * 3 + 2;bp2i * data2.Stride + j = (byte)value; img.UnlockBits(data);bit.UnlockBits(data2);ColorPalette palette = bit.Palette;for (int i = 0; i != palette.Entries.Length; i+)palette.Entriesi = Color.FromArgb(i, i, i);bit.P

19、alette = palette;bit.Save(E:/TEMP/bb.jpeg, ImageFormat.Jpeg); img.Dispose();bit.Dispose(); 代码中我使用了指针直接操作位图数据,同样的操作要比使用GetPixel, SetPixel快非常多。我们要感谢微软在C#中保留了特定情况下的指针操作。 图像效果如下: C+代码处理24位图转8位图 代码处理对于宽度和高度都为基数的图形处理会产生形变!核心部分代码如下:/代码中m_sourcefile指24位真彩色图片的位置,m_targetfile是转换后的256色BMP灰度图保存的位置void CMy24Dlg:

20、OnBtnConvert()UpdateData();if(m_sourcefile=|m_targetfile=) return; FILE *sourcefile,*targetfile;/位图文件头和信息头BITMAPFILEHEADER sourcefileheader,targetfileheader;BITMAPINFOHEADER sourceinfoheader,targetinfoheader;memset(&targetfileheader,0,sizeof(BITMAPFILEHEADER);memset(&targetinfoheader,0,sizeof(BITMAP

21、INFOHEADER);sourcefile=fopen(m_sourcefile,rb);fread(void*)&sourcefileheader,1,sizeof(BITMAPFILEHEADER),sourcefile);/提取原图文件头if(sourcefileheader.bfType!=0x4d42) fclose(sourcefile); MessageBox(原图象不为BMP图象!); return;fread(void*)&sourceinfoheader,1,sizeof(BITMAPINFOHEADER),sourcefile);/提取文件信息头if(sourceinf

22、oheader.biBitCount!=24) fclose(sourcefile); MessageBox(原图象不为24位真彩色!); return;if(sourceinfoheader.biCompression!=BI_RGB) fclose(sourcefile); MessageBox(原图象为压缩后的图象,本程序不处理压缩过的图象!); return;/构造灰度图的文件头targetfileheader.bfOffBits=54+sizeof(RGBQUAD)*256;targetfileheader.bfSize=targetfileheader.bfOffBits+sour

23、ceinfoheader.biSizeImage/3;targetfileheader.bfReserved1=0;targetfileheader.bfReserved2=0;targetfileheader.bfType=0x4d42;/构造灰度图的信息头targetinfoheader.biBitCount=8;targetinfoheader.biSize=40;targetinfoheader.biHeight=sourceinfoheader.biHeight;targetinfoheader.biWidth=sourceinfoheader.biWidth;targetinfoh

24、eader.biPlanes=1;targetinfoheader.biCompression=BI_RGB;targetinfoheader.biSizeImage=sourceinfoheader.biSizeImage/3;targetinfoheader.biXPelsPerMeter=sourceinfoheader.biXPelsPerMeter;targetinfoheader.biYPelsPerMeter=sourceinfoheader.biYPelsPerMeter;targetinfoheader.biClrImportant=0;targetinfoheader.bi

25、ClrUsed=256;构造灰度图的调色版RGBQUAD rgbquad256;int i,j,m,n,k;for(i=0;i256;i+) rgbquadi.rgbBlue=i; rgbquadi.rgbGreen=i; rgbquadi.rgbRed=i; rgbquadi.rgbReserved=0;targetfile=fopen(m_targetfile,wb);/写入灰度图的文件头,信息头和调色板信息fwrite(void*)&targetfileheader,1,sizeof(BITMAPFILEHEADER),targetfile);fwrite(void*)&targetin

26、foheader,1,sizeof(BITMAPINFOHEADER),targetfile);fwrite(void*)&rgbquad,1,sizeof(RGBQUAD)*256,targetfile);BYTE* sourcebuf;BYTE* targetbuf;/这里是因为BMP规定保存时长度和宽度必须是4的整数倍,如果不是则要补足m=(targetinfoheader.biWidth/4)*4;if(mtargetinfoheader.biWidth) m=m+4;n=(targetinfoheader.biHeight/4)*4;if(ntargetinfoheader.biHe

27、ight) n=n+4;sourcebuf=(BYTE*)malloc(m*n*3);/读取原图的颜色矩阵信息fread(sourcebuf,1,m*n*3,sourcefile);fclose(sourcefile);targetbuf=(BYTE*)malloc(m*n);BYTE color3; 通过原图颜色矩阵信息得到灰度图的矩阵信息for(i=0;in;i+) for(j=0;jm;j+) for(k=0; k255) targetbuf(i*m)+j=255; fwrite(void*)targetbuf,1,m*n+1,targetfile);fclose(targetfile)

28、;MessageBox(位图文件转换成功!); 24位真彩色和转换后的灰度图 上边的两组图就是用那段代码处理的结果 另外一种C+代码 BOOL Trans24To8(HDIB m_hDIB)/判断8位DIB是否为空if(m_hDIB1!=NULL):GlobalUnlock(HGLOBAL)m_hDIB1);:GlobalFree(HGLOBAL)m_hDIB1);m_hDIB1=NULL; BITMAPINFOHEADER* pBmpH; /指向信息头的指针m_hDIB1=(HDIB):GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(BITMAPINFOHEADER)+768*576+256*sizeof(RGBQUAD);

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2