欢迎来到冰点文库! | 帮助中心 分享价值,成长自我!
冰点文库
全部分类
  • 临时分类>
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • ImageVerifierCode 换一换
    首页 冰点文库 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

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

    • 资源ID:4368950       资源大小:703.28KB        全文页数:26页
    • 资源格式: DOCX        下载积分:1金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要1金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    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);


    注意事项

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

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

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

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


    收起
    展开