📄 chap05.htm
字号:
<p style='line-height:18.0pt'><span> </span>
(LPBITMAPINFO)lpTempImgData,</p>
<p style='line-height:
18.0pt'><span lang=EN-US>DIB_RGB_COLORS);</span></p>
<p style='line-height:18.0pt'><span
lang=EN-US>if(hPalette && hPrevPalette){</span></p>
<p style='line-height:18.0pt'><span>
</span>SelectPalette(hDc,hPrevPalette,FALSE);</p>
<p style='line-height:18.0pt'><span>
</span>RealizePalette(hDc);</p>
<p style='line-height:18.0pt'><span> </span>}</p>
<p style='line-height:18.0pt'><span
lang=EN-US>hf=_lcreat("c:\\gray.bmp",0);</span></p>
<p style='line-height:18.0pt'><span> </span>_lwrite(hf,(LPSTR)&DstBf,sizeof(BITMAPFILEHEADER));
</p>
<p style='line-height:18.0pt'><span> </span>_lwrite(hf,(LPSTR)lpTempImgData,DstBufSize);</p>
<p style='line-height:18.0pt'><span> </span>_lclose(hf);</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> ReleaseDC(hWnd,hDc);</p>
<p style='line-height:18.0pt'><span> </span>LocalUnlock(hTempImgData);</p>
<p style='line-height:18.0pt'><span> </span>LocalFree(hTempImgData);</p>
<p style='line-height:18.0pt'><span> </span>GlobalUnlock(hImgData);</p>
<p style='line-height:18.0pt'><span> </span>return
TRUE;</p>
<p style='line-height:18.0pt'><span lang=EN-US>}</span></p>
<h2> <span
lang=EN-US>5.3</span> <span lang=EN-US> </span><a name="_Toc486331884"></a><a
name="_Toc486332884"></a><a name="_Toc486338993"></a><a name="_Toc454810858"></a><a
name="_Toc454856632"><span><span>真彩图转<span lang=EN-US>256</span></span></span></a><span><span><span style='font-family:黑体;'>色图</span></span></span><span lang=EN-US>
</span></h2>
<p style='line-height:18.0pt'><span
style='font-family:宋体;"Times New Roman"'>我们知道,真彩图中包含最多达</span><span lang=EN-US>2<sup>24</sup></span><span
style='font-family:宋体;"Times New Roman"'>种颜色,怎样从中选出</span><span lang=EN-US>256</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>3</span><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>2</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>3</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>256</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>256</span><span
style='font-family:宋体;"Times New Roman"'>色图的转换。它的思想是:准备一个长度为</span><span lang=EN-US>4096</span><span
style='font-family:宋体;"Times New Roman"'>的数组,代表</span><span lang=EN-US>4096</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>12</span><span
style='font-family:宋体;"Times New Roman"'>位的整数,对应的数组元素加</span><span lang=EN-US>1</span><span
style='font-family:宋体;"Times New Roman"'>。全部统计完后,就得到了这</span><span lang=EN-US>4096</span><span
style='font-family:宋体;"Times New Roman"'>种颜色的使用频率。其中,可能有一些颜色一次也没用到,即对应的数组元素为零</span><span lang=EN-US>(</span><span
style='font-family:宋体;"Times New Roman"'>假设不为零的数组元素共有</span><span lang=EN-US>PalCounts</span><span
style='font-family:宋体;"Times New Roman"'>个</span><span lang=EN-US>)</span><span style='font-family:
宋体;"Times New Roman"'>。将这些为零的数组元素清除出去,使得前</span><span
lang=EN-US>PalCounts</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>个元素都不为零。将这</span><span
lang=EN-US>PalCounts</span><span style='font-family:宋体;"Times New Roman";"Times New Roman"'>个数按从大到小的顺序排列</span><span
lang=EN-US>(</span><span style='font-family:宋体;
"Times New Roman"'>这里我们使用起泡排序</span><span lang=EN-US>)</span><span
style='font-family:宋体;"Times New Roman"'>。这样,前</span><span lang=EN-US>256</span><span
style='font-family:宋体;"Times New Roman"'>种颜色就是用的最多的颜色,它们将作为调色板上的</span><span lang=EN-US>256</span><span
style='font-family:宋体;"Times New Roman"'>种颜色。对于剩下的</span><span lang=EN-US>PalCounts-256</span><span
style='font-family:宋体;"Times New Roman"'>种颜色并不是简单地丢弃,而是用前</span><span lang=EN-US>256</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>12</span><span style='font-family:宋体;
"Times New Roman"'>位的整数,如果对应值在前</span><span lang=EN-US>256</span><span
style='font-family:宋体;"Times New Roman"'>种颜色中,则直接将该索引值填入位图数据中,如果是在后</span><span lang=EN-US>PalCounts-256</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>5.3</span><span
style='font-family:宋体;"Times New Roman"'>是原真彩图,图</span><span lang=EN-US>.54</span><span
style='font-family:宋体;"Times New Roman"'>是用上面的算法转换成的</span><span lang=EN-US>256</span><span
style='font-family:宋体;"Times New Roman"'>色图,可以看出,效果还不错。</span></p>
<table border=0 cellspacing=0 cellpadding=0>
<tr>
<td width=276 valign=top class="Normal">
<p class=a style='line-height:18.0pt'><span lang=EN-US> <img width=220 height=200
src="chap05.files/image008.jpg" v:shapes="_x0000_i1028"> </span></p>
<p class=a style='line-height:18.0pt'><b><span style='font-family:宋体;
"Times New Roman"'>图</span>5.3 </b><b><span
style='font-family:宋体;"Times New Roman"'>原真彩图</span><span lang=EN-US></span></b></p>
</td>
<td width=276 valign=top class="Normal">
<p class=a style='line-height:18.0pt'><span lang=EN-US> <img width=220 height=200
src="chap05.files/image009.gif" v:shapes="_x0000_i1029"> </span></p>
<p class=a style='line-height:18.0pt'><b><span style='font-family:宋体;
"Times New Roman"'>图</span>5.4 </b><b><span
style='font-family:宋体;"Times New Roman"'>转换后的</span><span lang=EN-US>256</span></b><b><span
style='font-family:宋体;"Times New Roman"'>色图</span><span lang=EN-US></span></b></p>
</td>
</tr>
</table>
<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 Trueto256(HWND hWnd)</span></p>
<p style='line-height:18.0pt'><span lang=EN-US>{</span></p>
<p style='line-height:18.0pt'>DWORD
SrcBufSize,OffBits,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'><span> </span> HPALETTE
hPrevPalette;
</p>
<p style='line-height:18.0pt'><span> </span>HLOCAL
hPal;</p>
<p style='line-height:18.0pt'><span> </span>WORD
i,j;</p>
<p style='line-height:18.0pt'><span> </span>int
Red,Green,Blue,ClrIndex;</p>
<p style='line-height:18.0pt'><span> </span>DWORD
ColorHits[4096];</p>
<p style='line-height:18.0pt'><span> </span>WORD
ColorIndex[4096];</p>
<p style='line-height:18.0pt'><span> </span>DWORD
PalCounts,temp;</p>
<p style='line-height:18.0pt'><span> </span>long
ColorError1,ColorError2;</p>
<p style='line-height:18.0pt'><span> </span>if(NumColors!=0){
//NumColors<span style='font-
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -