📄 chap05.htm
字号:
宋体;"Times New Roman"'>章中提到了</span><span
lang=EN-US>YUV</span><span style='font-family:宋体;
"Times New Roman"'>的颜色表示方法,在这种表示方法中,</span><span
lang=EN-US>Y</span><span style='font-family:宋体;
"Times New Roman"'>分量的物理含义就是亮度,它含了灰度图</span><span
lang=EN-US>(grayscale)</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>的所有信息,只用</span><span
lang=EN-US>Y</span><span style='font-family:宋体;
"Times New Roman"'>分量就完全能够表示出一幅灰度图来。</span><span
lang=EN-US>YUV</span><span style='font-family:宋体;
"Times New Roman"'>和</span><span lang=EN-US>RGB</span><span
style='font-family:宋体;"Times New Roman"'>之间有着如下的对应关系:</span></p>
<p align=center style='text-align:center;line-height:18.0pt'><span
lang=EN-US><sub> <img width=352 height=77
src="chap05.files/image006.gif" v:shapes="_x0000_i1027"> </sub> </span></p>
<p style='line-height:18.0pt'><span
style='font-family:宋体;"Times New Roman"'>我们利用上式,根据</span><span lang=EN-US>R</span><span
style='font-family:宋体;"Times New Roman"'>、</span><span lang=EN-US>G</span><span style='font-family:
宋体;"Times New Roman"'>、</span><span
lang=EN-US>B</span><span style='font-family:宋体;
"Times New Roman"'>的值求出</span><span lang=EN-US>Y</span><span
style='font-family:宋体;"Times New Roman"'>值后,将</span><span lang=EN-US>R</span><span style='font-family:
宋体;"Times New Roman"'>、</span><span
lang=EN-US>G</span><span style='font-family:宋体;
"Times New Roman"'>、</span><span lang=EN-US>B</span><span
style='font-family:宋体;"Times New Roman"'>值都赋值成</span><span lang=EN-US>Y</span><span style='font-family:
宋体;"Times New Roman"'>,就能表示出灰度图来,这就是彩色图转灰度图的原理。</span></p>
<p style='line-height:18.0pt'><span
style='font-family:宋体;"Times New Roman"'>先看看真彩图。我们知道真彩图不带调色板,每个象素用</span><span lang=EN-US>3</span><span
style='font-family:宋体;"Times New Roman"'>个字节,表示</span><span lang=EN-US>R</span><span
style='font-family:宋体;"Times New Roman"'>、</span><span lang=EN-US>G</span><span style='font-family:
宋体;"Times New Roman"'>、</span><span
lang=EN-US>B</span><span style='font-family:宋体;
"Times New Roman"'>三个分量。所以处理很简单,根据</span><span
lang=EN-US>R</span><span style='font-family:宋体;
"Times New Roman"'>、</span><span lang=EN-US>G</span><span
style='font-family:宋体;"Times New Roman"'>、</span><span lang=EN-US>B</span><span style='font-family:
宋体;"Times New Roman"'>的值求出</span><span
lang=EN-US>Y</span><span style='font-family:宋体;
"Times New Roman"'>值后,将</span><span lang=EN-US>R</span><span
style='font-family:宋体;"Times New Roman"'>、</span><span lang=EN-US>G</span><span style='font-family:
宋体;"Times New Roman"'>、</span><span
lang=EN-US>B</span><span style='font-family:宋体;
"Times New Roman"'>值都赋值成</span><span lang=EN-US>Y</span><span
style='font-family:宋体;"Times New Roman"'>,写入新图即可。</span></p>
<p style='line-height:18.0pt'><span
style='font-family:宋体;"Times New Roman"'>再来看看带调色板的彩色图,我们知道位图中的数据只是对应调色板中的一个索引值,我们只需要将调色板中的彩色变成灰度,形成新调色板,而位图数据不用动,就可以了。</span></p>
<p style='line-height:18.0pt'><span
style='font-family:宋体;"Times New Roman"'>下面的程序实现了彩色图到灰度图的转换,注意其中真彩图和调色板位图处理时的差别。</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>BOOL ColortoGrayScale(HWND hWnd)</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>{</span></p>
<p style='line-height:18.0pt'>DWORD
SrcOffBits,SrcBufSize,DstBufSize,DstLineBytes;</p>
<p style='line-height:18.0pt'>LPBITMAPINFOHEADER lpImgData;</p>
<p style='line-height:18.0pt'><span> </span>LPSTR
lpPtr;</p>
<p style='line-height:18.0pt'><span> </span>HLOCAL
hTempImgData;</p>
<p style='line-height:18.0pt'><span> </span>LPBITMAPINFOHEADER
lpTempImgData;</p>
<p style='line-height:18.0pt'><span> </span>LPSTR
lpTempPtr;</p>
<p style='line-height:18.0pt'><span> </span>HDC
hDc;</p>
<p style='line-height:18.0pt'><span> </span>HFILE
hf;</p>
<p style='line-height:18.0pt'><span> </span>LONG
x,y;</p>
<p style='line-height:18.0pt'><span> </span>BITMAPFILEHEADER
DstBf;</p>
<p style='line-height:18.0pt'><span> </span>BITMAPINFOHEADER
DstBi;</p>
<p style='line-height:18.0pt'>LOGPALETTE
*pPal;</p>
<p style='line-height:18.0pt'>HPALETTE
hPrevPalette; </p>
<p style='line-height:18.0pt'><span> </span>HLOCAL
hPal;</p>
<p style='line-height:18.0pt'><span> </span>DWORD
NewNumColors;</p>
<p style='line-height:18.0pt'><span> </span>WORD
NewBitCount;</p>
<p style='line-height:18.0pt'><span> </span>float
Y;</p>
<p style='line-height:18.0pt'><span> </span>DWORD
i;</p>
<p style='line-height:18.0pt'><span> </span>unsigned
char Red,Green,Blue,Gray;</p>
<p style='line-height:18.0pt'><span> </span>NewNumColors=NumColors;
//NewNumColors<span style='font-family:宋体;
"Times New Roman"'>为新图的颜色数</span></p>
<p style='line-height:18.0pt'><span> </span>NewBitCount=bi.biBitCount;
//NewBitCount<span
style='font-family:宋体;"Times New Roman"'>为新图的颜色位数</span></p>
<p style='line-height:18.0pt'><span> </span>if(NumColors==0)
//<span style='font-family:宋体;
"Times New Roman"'>真彩图</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>{</span></p>
<p style='line-height:18.0pt'><span>
</span>NewNumColors=256;</p>
<p style='line-height:18.0pt'><span>
</span>NewBitCount=8;</p>
<p style='line-height:18.0pt'><span> </span>}</p>
<p style='line-height:18.0pt'><span
lang=EN-US>//</span><span style='font-family:宋体;
"Times New Roman"'>由于颜色位数有可能发生了改变,所以要重新计算每行占用的字节数以及</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>//</span><span style='font-family:宋体;
"Times New Roman"'>新图的缓冲区大小</span></p>
<p style='line-height:18.0pt'><span> </span>DstLineBytes=(DWORD)WIDTHBYTES(bi.biWidth*NewBitCount);</p>
<p style='line-height:18.0pt'><span> </span>DstBufSize=(DWORD)(sizeof(BITMAPINFOHEADER)+NewNumColors*</p>
<p style='line-height:
18.0pt'><span lang=EN-US>sizeof(RGBQUAD)+(DWORD)DstLineBytes*bi.biHeight);</span></p>
<p style='line-height:18.0pt'><span> </span><a name=b1></a>//DstBf<span
style='font-family:宋体;"Times New Roman"'>和</span><span lang=EN-US>DstBi</span><span style='font-family:
宋体;"Times New Roman"'>为新的</span><span
lang=EN-US>BITMAPFILEHEADER</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>和</span><span
lang=EN-US>BITMAPINFOHEADER</span></p>
<p style='line-height:18.0pt'><span> </span>//<span
style='font-family:宋体;"Times New Roman"'>拷贝原来的头信息</span></p>
<p style='line-height:18.0pt'><span> </span>memcpy((char
*)&DstBf,(char *)&bf,sizeof(BITMAPFILEHEADER));</p>
<p style='line-height:18.0pt'><span> </span>memcpy((char
*)&DstBi,(char *)&bi,sizeof(BITMAPINFOHEADER));</p>
<p style='line-height:18.0pt'><span> </span>//<span
style='font-family:宋体;"Times New Roman"'>做必要的改变</span></p>
<p style='line-height:18.0pt'><span> </span>DstBf.bfSize=DstBufSize+sizeof(BITMAPFILEHEADER);</p>
<p style='line-height:18.0pt'><span> </span>DstBf.bfOffBits=(DWORD)(NewNumColors*sizeof(RGBQUAD)+</p>
<p style='line-height:
18.0pt'><span lang=EN-US>sizeof(BITMAPFILEHEADER)+</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>sizeof(BITMAPINFOHEADER));</span></p>
<p style='line-height:18.0pt'><span> </span>DstBi.biClrUsed=0;</p>
<p style='line-height:18.0pt'><span> </span>DstBi.biBitCount=NewBitCount;</p>
<p style='line-height:18.0pt'><span> </span>//<span
style='font-family:宋体;"Times New Roman"'>原图的缓冲区的大小</span></p>
<p style='line-height:18.0pt'><span> </span>SrcOffBits=bf.bfOffBits-
sizeof(BITMAPFILEHEADER);</p>
<p style='line-height:18.0pt'><span
lang=EN-US>SrcBufSize=SrcOffBits+bi.biHeight*LineBytes;</span></p>
<p style='line-height:18.0pt'><span> </span>if((hTempImgData=LocalAlloc(LHND,DstBufSize))==NULL)</p>
<p style='line-height:18.0pt'><span
lang=EN-US>{</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>MessageBox(hWnd,"Error alloc memory!","Error
Message",MB_OK|</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>MB_ICONEXCLAMATION);</span></p>
<p style='line-height:
18.0pt'><span lang=EN-US>return FALSE;</span></p>
<p style='line-height:18.0pt'><span> </span>}</p>
<p style='line-height:18.0pt'><span> </span> lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
</p>
<p style='line-height:18.0pt'><span> </span>lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);</p>
<p style='line-height:18.0pt'><span
lang=EN-US>//</span><span style='font-family:宋体;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -