




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
24位真彩色轉(zhuǎn)換為8位灰度圖//////////////////////////////////////////////////////////////////////////#include<windows.h>BOOLBMP24to8(char*szSourceFile,char*szTargetFile);intmain(intargc,char*argv[])
{//調(diào)用這個(gè)函數(shù)直接把24位真彩色灰度化BOOLstat=BMP24to8("c://source.bmp","c://target.bmp");return0;}BOOLBMP24to8(char*szSourceFile,char*szTargetFile){HANDLEhSourceFile=INVALID_HANDLE_VALUE,hTargetFile=INVALID_HANDLE_VALUE;
DWORDdwSourceSize=0,dwTargetSize=0;PBYTEpSource=NULL,pTarget=NULL;hSourceFile=CreateFile(szSourceFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hSourceFile==INVALID_HANDLE_VALUE)returnFALSE;dwSourceSize=GetFileSize(hSourceFile,NULL);
pSource=(PBYTE)VirtualAlloc(NULL,dwSourceSize,MEM_COMMIT,PAGE_READWRITE);//分配空間失敗或者文件太小(BMP文件不可能小于54個(gè)字節(jié))if(pSource==NULL||dwSourceSize<=54){CloseHandle(hSourceFile);returnFALSE;}DWORDdwTemp=0;ReadFile(hSourceFile,pSource,dwSourceSize,&dwTemp,NULL);BITMAPFILEHEADER*pSourceFileHeader=(BITMAPFILEHEADER*)pSource;BITMAPINFOHEADER*pSourceInfoHeader=(BITMAPINFOHEADER*)(pSource+sizeof(BITMAPFILEHEADER));//不是BMP文件或者不是24位真彩色if(pSourceFileHeader->bfType!=0x4d42||pSourceInfoHeader->biBitCount!=24){CloseHandle(hSourceFile);VirtualFree(pSource,NULL,MEM_RELEASE);returnFALSE;}CloseHandle(hSourceFile);LONGnWidth=pSourceInfoHeader->biWidth;LONGnHeight=pSourceInfoHeader->biHeight;LONGnSourceWidth=nWidth*3;if(nSourceWidth%4)nSourceWidth=(nSourceWidth/4+1)*4;LONGnTargetWidth=nWidth;if(nTargetWidth%4)nTargetWidth=(nTargetWidth/4+1)*4;dwTargetSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256+nHeight*nTargetWidth;pTarget=(PBYTE)VirtualAlloc(NULL,dwTargetSize,MEM_COMMIT,PAGE_READWRITE);memset(pTarget,0,dwTargetSize);if(pTarget==NULL){VirtualFree(pTarget,NULL,MEM_RELEASE);returnFALSE;}BITMAPFILEHEADER*pTargetFileHeader=(BITMAPFILEHEADER*)pTarget;BITMAPINFOHEADER*pTargetInfoHeader=(BITMAPINFOHEADER*)(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;pTargetInfoHeader->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=nHeight*nTargetWidth;pTargetInfoHeader->biWidth=pSourceInfoHeader->biWidth;pTargetInfoHeader->biXPelsPerMeter=pSourceInfoHeader->biXPelsPerMeter;pTargetInfoHeader->biYPelsPerMeter=pSourceInfoHeader->biYPelsPerMeter;RGBQUAD*pRgb;for(inti=0;i<256;i++)//初始化8位灰度圖的調(diào)色板信息{pRgb=(RGBQUAD*)(pTarget+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+i*sizeof(RGBQUAD));pRgb->rgbBlue=i;pRgb->rgbGreen=i;pRgb->rgbRed=i;pRgb->rgbReserved=0;}for(intm=0;m<nHeight;m++)//轉(zhuǎn)化真彩色圖為灰度圖{for(intn=0;n<nWidth;n++){pTarget[pTargetFileHeader->bfOffBits+m*nTargetWidth+n]=pSource[pSourceFileHeader->bfOffBits+m*nSourceWidth+n*3]*0.114+pSource[pSourceFileHeader->bfOffBits+m*nSourceWidth+n*3+1]*0.587+pSource[pSourceFileHeader->bfOffBits+m*nSourceWidth+n*3+2]*0.299;}}hTargetFile=CreateFile(szTargetFile,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);BOOLstat=WriteFile(hTargetFile,pTarget,dwTargetSize,&dwTemp,NULL);CloseHandle(hTargetFile);VirtualFree(pSource,NULL,MEM_RELEASE);VirtualFree(pTarget,NULL,MEM_RELEASE);returnstat;}轉(zhuǎn)化效果如下圖在GDI+中將24位真彩色圖轉(zhuǎn)換為灰度圖(原理、C#調(diào)用指針)在圖像處理中,我們經(jīng)常需要將真彩色圖像轉(zhuǎn)換為黑白圖像。嚴(yán)格的講應(yīng)該是灰度圖,因?yàn)檎嬲暮诎讏D像是二色,即只有純黑,純白二色。開(kāi)始之前,我們先簡(jiǎn)單補(bǔ)充一下計(jì)算機(jī)中圖像的表示原理。計(jì)算機(jī)中的圖像大致可以分成兩類:位圖(Bitmap)和矢量圖(Metafile)。位圖可以視為一個(gè)二維的網(wǎng)格,整個(gè)圖像就是由很多個(gè)點(diǎn)組成的,點(diǎn)的個(gè)數(shù)等于位圖的寬乘以高。每個(gè)點(diǎn)被稱為一個(gè)像素點(diǎn),每個(gè)像素點(diǎn)有確定的顏色,當(dāng)很多個(gè)像素合在一起時(shí)就形成了一幅完整的圖像。我們通常使用的圖像大部分都是位圖,如數(shù)碼相機(jī)拍攝的照片,都是位圖。因?yàn)槲粓D可以完美的表示圖像的細(xì)節(jié),能較好的還原圖像的原景。但位圖也有缺點(diǎn):第一是體積比較大,所以人們開(kāi)發(fā)了很多壓縮圖像格式來(lái)儲(chǔ)存位圖圖像,目前應(yīng)用最廣的是JPEG格式,在WEB上得到了廣泛應(yīng)用,另外還有GIF,PNG等等。第二是位圖在放大時(shí),不可避免的會(huì)出現(xiàn)“鋸齒”現(xiàn)象,這也由位圖的本質(zhì)特點(diǎn)決定的。所以在現(xiàn)實(shí)中,我們還需要使用到另一種圖像格式:矢量圖。同位圖不同,矢量圖同位圖的原理不同,矢量圖是利用數(shù)學(xué)公式通過(guò)圓,線段等繪制出來(lái)的,所以不管如何放大都不會(huì)出現(xiàn)變形,但矢量圖不能描述非常復(fù)雜的圖像。所以矢量圖都是用來(lái)描述圖形圖案,各種CAD軟件等等都是使用矢量格式來(lái)保存文件的。在講解顏色轉(zhuǎn)換之前,我們要先對(duì)位圖的顏色表示方式做一了解。位圖中通常是用RGB三色方式來(lái)表示顏色的(位數(shù)很少時(shí)要使用調(diào)色板)。所以每個(gè)像素采用不同的位數(shù),就可以表示出不同數(shù)量的顏色。如下圖所示:每像素的位數(shù)一個(gè)像素可分配到的顏色數(shù)量12^1=222^2=442^4=1682^8=256162^16=65,536242^24=16,777,216從中我們可以看出,當(dāng)使用24位色(3個(gè)字節(jié))時(shí),我們可以得到1600多萬(wàn)種顏色,這已經(jīng)非常豐富了,應(yīng)該已接近人眼所能分辨的顏色了?,F(xiàn)在計(jì)算機(jī)中使用最多的就是24位色,別外在GDI+中還有一種32位色,多出來(lái)的一個(gè)通道用來(lái)描述Alpha,即透明分量。24位色中3個(gè)字節(jié)分別用來(lái)描述R,G,B三種顏色分量,我們看到這其中是沒(méi)有亮度分量的,這是因?yàn)樵赗GB表示方式中,亮度也是直接可以從顏色分量中得到的,每一顏色分量值的范圍都是從0到255,某一顏色分量的值越大,就表示這一分量的亮度值越高,所以255表示最亮,0表示最暗。那么一個(gè)真彩色像素點(diǎn)轉(zhuǎn)換為灰度圖時(shí)它的亮度值應(yīng)該是多少呢,首先我們想到的平均值,即將R+G+B/3。但現(xiàn)實(shí)中我們使用的卻是如下的公式:Y=0.299R+0.587G+0.114B這個(gè)公式通常都被稱為心理學(xué)灰度公式。這里面我們看到綠色分量所占比重最大。因?yàn)榭茖W(xué)家發(fā)現(xiàn)使用上述公式進(jìn)行轉(zhuǎn)換時(shí)所得到的灰度圖最接近人眼對(duì)灰度圖的感覺(jué)。因?yàn)榛叶葓D中顏色數(shù)量一共只有256種(1個(gè)字節(jié)),所以轉(zhuǎn)換后的圖像我們通常保存為8位格式而不是24位格式,這樣比較節(jié)省空間。而8位圖像是使用調(diào)色板方式來(lái)保存顏色的。而不是直接保存顏色值。調(diào)色板中可以保存256顏色,所以可以正好可以將256種灰度顏色保存到調(diào)色版中。代碼如下:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Drawing;usingSystem.Drawing.Imaging;namespaceConsoleApplication2{classProgram{unsafestaticvoidMain(string[]args){Bitmapimg=(Bitmap)Image.FromFile(@"E:/MyDocuments/MyPictures/cherry_blossom_1002.jpg");Bitmapbit=newBitmap(img.Width,img.Height,PixelFormat.Format8bppIndexed);BitmapDatadata=img.LockBits(newRectangle(0,0,img.Width,img.Height),ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);byte*bp=(byte*)data.Scan0.ToPointer();BitmapDatadata2=bit.LockBits(newRectangle(0,0,bit.Width,bit.Height),ImageLockMode.ReadWrite,PixelFormat.Format8bppIndexed);byte*bp2=(byte*)data2.Scan0.ToPointer();for(inti=0;i!=data.Height;i++){for(intj=0;j!=data.Width;j++){//0.3R+0.59G+0.11Bfloatvalue=0.11F*bp[i*data.Stride+j*3]+0.59F*bp[i*data.Stride+j*3+1]+0.3F*bp[i*data.Stride+j*3+2];bp2[i*data2.Stride+j]=(byte)value;}}img.UnlockBits(data);bit.UnlockBits(data2);ColorPalettepalette=bit.Palette;for(inti=0;i!=palette.Entries.Length;i++){palette.Entries[i]=Color.FromArgb(i,i,i);}bit.Palette=palette;bit.Save(@"E:/TEMP/bb.jpeg",ImageFormat.Jpeg);img.Dispose();bit.Dispose();}}}代碼中我使用了指針直接操作位圖數(shù)據(jù),同樣的操作要比使用GetPixel,SetPixel快非常多。我們要感謝微軟在C#中保留了特定情況下的指針操作。圖像效果如下:C++代碼處理24位圖轉(zhuǎn)8位圖代碼處理對(duì)于寬度和高度都為基數(shù)的圖形處理會(huì)產(chǎn)生形變!核心部分代碼如下:////代碼中m_sourcefile指24位真彩色圖片的位置,m_targetfile是轉(zhuǎn)換后的256色BMP灰度圖保存的位置voidCMy24Dlg::OnBtnConvert(){UpdateData();
if(m_sourcefile==""||m_targetfile=="")
return;
FILE*sourcefile,*targetfile;//位圖文件頭和信息頭
BITMAPFILEHEADERsourcefileheader,targetfileheader;
BITMAPINFOHEADERsourceinfoheader,targetinfoheader;
memset(&targetfileheader,0,sizeof(BITMAPFILEHEADER));
memset(&targetinfoheader,0,sizeof(BITMAPINFOHEADER));
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(sourceinfoheader.biBitCount!=24)
{
fclose(sourcefile);
MessageBox("原圖象不為24位真彩色!");
return;
}
if(sourceinfoheader.biCompression!=BI_RGB)
{
fclose(sourcefile);
MessageBox("原圖象為壓縮后的圖象,本程序不處理壓縮過(guò)的圖象!");
return;
}//構(gòu)造灰度圖的文件頭
targetfileheader.bfOffBits=54+sizeof(RGBQUAD)*256;
targetfileheader.bfSize=targetfileheader.bfOffBits+sourceinfoheader.biSizeImage/3;
targetfileheader.bfReserved1=0;
targetfileheader.bfReserved2=0;
targetfileheader.bfType=0x4d42;//構(gòu)造灰度圖的信息頭
targetinfoheader.biBitCount=8;
targetinfoheader.biSize=40;
targetinfoheader.biHeight=sourceinfoheader.biHeight;
targetinfoheader.biWidth=sourceinfoheader.biWidth;
targetinfoheader.biPlanes=1;
targetinfoheader.biCompression=BI_RGB;
targetinfoheader.biSizeImage=sourceinfoheader.biSizeImage/3;
targetinfoheader.biXPelsPerMeter=sourceinfoheader.biXPelsPerMeter;
targetinfoheader.biYPelsPerMeter=sourceinfoheader.biYPelsPerMeter;
targetinfoheader.biClrImportant=0;
targetinfoheader.biClrUsed=256;構(gòu)造灰度圖的調(diào)色版RGBQUADrgbquad[256];
inti,j,m,n,k;
for(i=0;i<256;i++)
{
rgbquad[i].rgbBlue=i;
rgbquad[i].rgbGreen=i;
rgbquad[i].rgbRed=i;
rgbquad[i].rgbReserved=0;
}
targetfile=fopen(m_targetfile,"wb");//寫(xiě)入灰度圖的文件頭,信息頭和調(diào)色板信息
fwrite((void*)&targetfileheader,1,sizeof(BITMAPFILEHEADER),targetfile);
fwrite((void*)&targetinfoheader,1,sizeof(BITMAPINFOHEADER),targetfile);
fwrite((void*)&rgbquad,1,sizeof(RGBQUAD)*256,targetfile);
BYTE*sourcebuf;
BYTE*targetbuf;//這里是因?yàn)锽MP規(guī)定保存時(shí)長(zhǎng)度和寬度必須是4的整數(shù)倍,如果不是則要補(bǔ)足
m=(targetinfoheader.biWidth/4)*4;
if(m<targetinfoheader.biWidth)
m=m+4;
n=(targetinfoheader.biHeight/4)*4;
if(n<targetinfoheader.biHeight)
n=n+4;
sourcebuf=(BYTE*)malloc(m*n*3);//讀取原圖的顏色矩陣信息
fread(sourcebuf,1,m*n*3,sourcefile);
fclose(sourcefile);
targetbuf=(BYTE*)malloc(m*n);
BYTEcolor[3];通過(guò)原圖顏色矩陣信息得到灰度圖的矩陣信息
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
for(k=0;k<3;k++)
color[k]=sourcebuf[(i*m+j)*3+k];
targetbuf[(i*m)+j]=color[0]*0.114+color[1]*0.587+color[2]*0.299;
if(targetbuf[(i*m)+j]>255)
targetbuf[(i*m)+j]=255;
}
}
fwrite((void*)targetbuf,1,m*n+1,targetfile);
fclose(targetfile);
MessageBox("位圖文件轉(zhuǎn)換成功!");}24位真彩色和轉(zhuǎn)換后的灰度圖上邊的兩組圖就是用那段代碼處理的結(jié)果另外一種C++代碼BOOLTrans24To8(HDIBm_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));lpDIB1=(LPSTR)::GlobalLock(m_hDIB1);pBmpH=(BITMAPINFOHEADER*)(lpDIB1);
pImageBuffer=(unsignedchar*)lpDIB1+40+256*4;//指向8位DIB圖象數(shù)據(jù)的指針//寫(xiě)bmp信息頭及bmp調(diào)色版WriteBMPHeader(lpDIB1);LPSTRlpDIB=(LPSTR)::GlobalLock((HGLOBAL)m_hDIB);//得到24位DIB的指針intWidthDIB=(int):IBWidth(lpDIB);intHeightDIB=(int):IBHeight(lpDIB);LPSTRlp=::FindDIBBits(lpDIB);unsignedchar*l;for(intj=0;j<HeightDIB;j++){for(inti=0;i<WidthDIB;i++){l=(unsignedchar*)lp+(j*768+i)*3;*pImageBuffer=(int)(((*l)*30+(*(l+1))*59+(*(l+2))*11)/100);pImageBuffer++;}}pImageBuffer-=768*576;
Invalidate(TRUE);//隱含調(diào)用OnDraw()函數(shù)繪圖,即顯示轉(zhuǎn)化后的圖象
returnTRUE;}
voidCBoKeDetectView::WriteBMPHeader(LPSTR&lpDIB)
{//寫(xiě)bmp信息頭BITMAPINFOHEADER*pBmpInfoHeader;
pBmpInfoHeader=(BITMAPINFOHEADER*)lpDIB;
pBmpInfoHeader->biSize=sizeof(BITMAPINFOHEADER);
pBmpInfoHeader->biWidth=768;
pBmpInfoHeader->biHeight=576;
pBmpInfoHeader->biBitCount=8;
pBmpInfoHeader->biPlanes=1;
pBmpInfoHeader->biCompression=BI_RGB;
pBmpInfoHeader->biSizeImage=0;
pBmpInfoHeader->biXPelsPerMeter=0;
pBmpInfoHeader->biYPelsPerMeter=0;
pBmpInfoHeader->biClrUsed=0;
pBmpInfoHeader->biClrImportant=0;//寫(xiě)bmp調(diào)色版
RGBQUAD*pRGB=(RGBQUAD*)(lpDIB+40);
for(inti=0;i<256;i++){pRGB.rgbBlue=pRGB.rgbGreen=pRGB.rgbRed=i;
pRGB.rgbReserved=0;}}C#兩種獲取灰度圖像的方法(24位轉(zhuǎn)8位)在圖像處理程序開(kāi)發(fā)中,常會(huì)遇到將一幅彩色圖像轉(zhuǎn)換成灰度圖像的情況,筆者在最近的一個(gè)項(xiàng)目中便遇到了這點(diǎn)。經(jīng)過(guò)一翻努力最終解決,想想有必要分享一下,于是便寫(xiě)下此文。在本文中,將向各位讀者介紹兩種實(shí)現(xiàn)這一變換的方法,這也是筆者先后使用的兩種方法。本文的例子使用C#語(yǔ)言編寫(xiě),使用的集成開(kāi)發(fā)環(huán)境是VisualStudio2005。第一種,直接調(diào)用GetPixel/SetPixel方法。我們都知道,圖像在計(jì)算機(jī)中的存在形式是位圖,也即一個(gè)矩形點(diǎn)陣,每一個(gè)點(diǎn)被稱為一個(gè)像素。在這種方法中,我們通過(guò)GDI+中提供的GetPixel方法來(lái)讀取像素的顏色,并加以計(jì)算,然后再使用SetPixel方法將計(jì)算后的顏色值應(yīng)用到相應(yīng)的像素上去,這樣便可以得到灰度圖像。上邊提到的“計(jì)算”便是指得到灰度圖像的計(jì)算,其公式是:r=(像素點(diǎn)的紅色分量+像素點(diǎn)的綠色分量+像素點(diǎn)的藍(lán)色分量)/3最后得到的r便是需要應(yīng)用到原像素點(diǎn)的值。具體的編程實(shí)現(xiàn)也非常的簡(jiǎn)單,只需要遍歷位圖的每一個(gè)像素點(diǎn),然后使用SetPixel方法將上邊計(jì)算得到的值應(yīng)用回去即可。主要代碼如下所示:ColorcurrentColor;intr;BitmapcurrentBitmap=newBitmap(picBox.Image);Graphicsg=Graphics.FromImage(currentBitmap);for(intw=0;w<currentBitmap.Width;w++){for(inth=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();以上代碼非常簡(jiǎn)單,不需要做太多的解釋。需要注意的是,在使用SetPixel方法的時(shí)候,其三色分量值均為我們公式計(jì)算得到的結(jié)果r。另外一種寫(xiě)法privatevoidToolStripMenuItemGrayR_Click(objectsender,EventArgse){Bitmapb=newBitmap(pictureBox1.Image);//把圖片框1中的圖片給一個(gè)bitmap類型Bitmapb1=newBitmap(pictureBox1.Image);Colorc=newColor();//Graphicsg1=pictureBox1.CreateGraphics();//容器設(shè)為圖片框1for(inti=0;i<pictureBox1.Image.Width;i++)for(intj=0;j<pictureBox1.Image.Height;j++){c=b1.GetPixel(i,j);//用FromArgb方法由顏色分量值創(chuàng)建Color結(jié)構(gòu)Colorc1=Color.FromArgb(c.B,c.B,c.B);b1.SetPixel(i,j,c1);//pictureBox2.Image=b1;//pictureBox2.Refresh();}pictureBox2.Image=b1;pictureBox2.Refresh();}第二種,使用ColorMatrix類如果讀者親自測(cè)試過(guò)第一種方式,就會(huì)發(fā)現(xiàn)通過(guò)循環(huán)遍歷位圖所有像素,并使用SetPixel方法來(lái)修改每個(gè)像素的各顏色分量是非常耗時(shí)的。而現(xiàn)在介紹的第二種方法則是一種更好的實(shí)現(xiàn)方式――使用ColorMatrix類。在介紹具體的實(shí)現(xiàn)之前,有必要先向讀者介紹一下相關(guān)的背景知識(shí)。在GDI+中,顏色使用32位來(lái)保存,紅色、綠色、藍(lán)色和透明度分別占8位,因此每個(gè)分量可以有28=256(0~255)種取值。這樣一來(lái),一個(gè)顏色信息就可以用一個(gè)向量(Red,Green,Blue,Alpha)來(lái)表示,例如不透明的紅色可以表示成為(255,0,0,255)。向量中的Alpha值用來(lái)表示顏色的透明度,0表示完全透明,255表示完全不透明。到這里讀者朋友可能應(yīng)該想到了,我們只需要按照一定的規(guī)則改變這些向量里各個(gè)分量的值,便可以得到各種各樣的顏色變換效果,所以我們獲得灰度圖這個(gè)要求也就能夠?qū)崿F(xiàn)了?,F(xiàn)在關(guān)鍵問(wèn)題便是按照什么規(guī)則來(lái)改變各分量值。在上邊介紹的第一種方式中我們提到了計(jì)算灰度圖像的公式,其實(shí)它還有另外一個(gè)表示方式,如下:r=像素點(diǎn)的紅色分量×0.299+像素點(diǎn)的綠色分量×0.587+像素點(diǎn)的藍(lán)色分量×0.114這一公式便是我們的規(guī)則。我們只需要對(duì)每一個(gè)顏色向量做上邊的變化即可。這里的變換就需要用到ColorMatrix類,此類定義在System.Drawing.Imaging名字空間中,它定義了一個(gè)5×5的數(shù)組,用來(lái)記錄將和顏色向量進(jìn)行乘法計(jì)算的值。ColorMatrix對(duì)象配合ImageAttributes類一起使用,實(shí)際上GDI+里的顏色變換就是通過(guò)ImageAttributes對(duì)象的SetColorMatrix進(jìn)行的。第二種的主要實(shí)現(xiàn)代碼如下:BitmapcurrentBitmap=newBitmap(picBox.Image);Graphicsg=Graphics.FromImage(currentBitmap);ImageAttributesia=newImageAttributes();float[][]colorMatrix={newfloat[]{0.299f,0.299f,0.299f,0,0},newfloat[]{0.587f,0.587f,0.587f,0,0},newfloat[]{0.114f,0.114f,0.114f,0,0},newfloat[]{0,0,0,1,0},newfloat[]{0,0,0,0,1}};ColorMatrixcm=newColorMatrix(colorMatrix);ia.SetColorMatrix(cm,ColorMatrixFlag.Default,ColorAdjustType.Bitmap);g.DrawImage(currentBitmap,newRectangle(0,0,currentBitmap.Width,currentBitmap.Height),0,0,currentBitmap.Width,currentBitmap.Height,GraphicsUnit.Pixel,ia);picBox.Image=currentBitmap;g.Dispose();細(xì)心的讀者可能會(huì)問(wèn),明明顏色是由4個(gè)分量組成的,那么與之相乘的矩陣也應(yīng)該是一個(gè)4×4的矩陣啊,為什么這里定義的顏色變換矩陣卻是5×5的呢?這個(gè)問(wèn)題可以參考MSDN上的一篇文章(《使用顏色矩陣對(duì)單色進(jìn)行變換》)便可得解。請(qǐng)讀者朋友們輸入以上代碼并編譯執(zhí)行。大家會(huì)發(fā)現(xiàn)其變換速度極快,幾乎是瞬間完成。其實(shí),只要知道了矩陣各行、列必要的參數(shù)值,那么使用ColorMatrix來(lái)實(shí)現(xiàn)顏色變換是非常方便的。諸如讓某色透明這樣的功能用這種方式實(shí)現(xiàn)起來(lái)也是非常方便高效的。上邊簡(jiǎn)要地介紹了兩種獲得灰度圖像的方法。在實(shí)際開(kāi)發(fā)中,使用第二種方式遠(yuǎn)遠(yuǎn)優(yōu)于第一種,其在運(yùn)算速度方面的優(yōu)勢(shì),是第一種遠(yuǎn)遠(yuǎn)沒(méi)法比的。ColorMatrix類(.NETFramework4).NETFramework3.5.NETFramework3.0.NETFramework2.0定義包含RGBAW空間坐標(biāo)的5x5矩陣。ImageAttributes類的若干方法通過(guò)使用顏色矩陣調(diào)整圖像顏色。無(wú)法繼承此類。命名空間:System.Drawing.Imaging
程序集:System.Drawing(在System.Drawing.dll中)語(yǔ)法publicsealedclassColorMatrix備注矩陣系數(shù)組成一個(gè)5x5的線性轉(zhuǎn)換,用于轉(zhuǎn)換ARGB單色值。例如,ARGB向量表示為Alpha、Red(紅色)、Green(綠色)、Blue(藍(lán)色)和W,此處W始終為1。例如,假設(shè)您希望從顏色(0.2,0.0,0.4,1.0)開(kāi)始并應(yīng)用下面的變換:將紅色分量乘以2。將0.2添加到紅色、綠色和藍(lán)色分量中。下面的矩陣乘法將按照列出的順序進(jìn)行這對(duì)變換。顏色矩陣的元素按照先行后列(從0開(kāi)始)的順序進(jìn)行索引。例如,矩陣M的第五行第三列由M[4][2]表示。5×5單位矩陣(在下面的插圖中顯示)在對(duì)角線上為1,在其他任何地方為0。如果用單位矩陣乘以顏色矢量,則顏色矢量不會(huì)發(fā)生改變。形成顏色變換矩陣的一種簡(jiǎn)便方法是從單位矩陣開(kāi)始,然后進(jìn)行較小的改動(dòng)以產(chǎn)生所需的變換。有關(guān)矩陣和變換的更詳細(xì)的討論,請(qǐng)參見(jiàn)坐標(biāo)系統(tǒng)和變形。示例下面的示例采用一個(gè)使用一種顏色(0.2,0.0,0.4,1.0)的圖像,并應(yīng)用上一段中描述的變換。下面的插圖在左側(cè)顯示原來(lái)的圖像,在右側(cè)顯示變換后的圖像。下面示例中的代碼使用以下步驟進(jìn)行重新著色:初始化ColorMatrix對(duì)象。創(chuàng)建一個(gè)HYPERLINK"/zh-cn/library/system.drawing.imaging.ima
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 門(mén)診護(hù)理查對(duì)制度
- 汽修店年度分析報(bào)告范文
- 浙江國(guó)企招聘2024浙江省有色金屬地質(zhì)勘查院招聘7人筆試參考題庫(kù)附帶答案詳解
- 二零二五年度房產(chǎn)分割及父母子女贍養(yǎng)義務(wù)協(xié)議書(shū)
- 美容院合伙人二零二五年度市場(chǎng)拓展合作協(xié)議
- 二零二五年度養(yǎng)殖場(chǎng)養(yǎng)殖技術(shù)研發(fā)用工合同
- 二零二五年度二零二五年度時(shí)尚潮流門(mén)面房租賃合同
- 二零二五年度旅游客運(yùn)合同承運(yùn)人服務(wù)質(zhì)量及賠償責(zé)任承諾
- 二零二五年度形婚伴侶婚姻生活共同興趣愛(ài)好培養(yǎng)合同
- 二零二五年度農(nóng)田租賃合同范本(含農(nóng)業(yè)生態(tài)保護(hù))
- 借哪吒精神燃開(kāi)學(xué)斗志 開(kāi)學(xué)主題班會(huì)課件
- 2025年初中主題班會(huì)課件:好習(xí)慣成就好人生
- 學(xué)校教職工代表大會(huì)全套會(huì)議會(huì)務(wù)資料匯編
- GB/T 45107-2024表土剝離及其再利用技術(shù)要求
- 人教PEP版(2024)三年級(jí)上冊(cè)英語(yǔ)Unit 6《Useful numbers》單元作業(yè)設(shè)計(jì)
- 幼兒園安全教育課件:《危險(xiǎn)的小圓珠》
- 2020華夏醫(yī)學(xué)科技獎(jiǎng)知情同意報(bào)獎(jiǎng)證明
- 素描石膏幾何體
- 第二章 法國(guó)學(xué)前教育
- 精雕JDPaint常用快捷鍵
- 中興網(wǎng)管日常操作
評(píng)論
0/150
提交評(píng)論