?? 哈夫曼編碼.c
字號:
/////////////////////////////////////////////////////////////////////////////////////
// 圖像編碼
//
void CCh1_1View::OnCodeHuffman()
{
// 查看哈夫曼編碼表
// 獲取文檔
CCh1_1Doc* pDoc = GetDocument();
// 指向源圖像象素的指針
unsigned char * lpSrc;
// 指向DIB的指針
LPSTR lpDIB;
// 指向DIB象素指針
LPSTR lpDIBBits;
// DIB的高度
LONG lHeight;
// DIB的寬度
LONG lWidth;
// 圖像每行的字節數
LONG lLineBytes;
// 圖像象素總數
LONG lCountSum;
// 循環變量
LONG i;
LONG j;
// 保存各個灰度值頻率的數組指針
FLOAT * fFreq;
// 獲取當前DIB顏色數目
int iColorNum;
// 鎖定DIB
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
// 找到DIB圖像象素起始位置
lpDIBBits = ::FindDIBBits(lpDIB);
// 獲取當前DIB顏色數目
iColorNum = ::DIBNumColors(lpDIB);
// 判斷是否是8-bpp位圖(這里為了方便,只處理8-bpp位圖,其它的可以類推)
if (iColorNum != 256)
{
// 提示用戶
MessageBox("目前只支持256色位圖哈夫曼編碼!", "系統提示" ,
MB_ICONINFORMATION | MB_OK);
// 解除鎖定
::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
// 返回
return;
}
// 更改光標形狀
BeginWaitCursor();
/******************************************************************************
// 開始計算各個灰度級出現的頻率
//
// 如果需要對其它序列進行哈夫曼編碼,只需改動此處即可,例如,直接賦值:
iColorNum = 8;
fFreq = new FLOAT[iColorNum];
fFreq[0] = 0.04;
fFreq[1] = 0.05;
fFreq[2] = 0.06;
fFreq[3] = 0.07;
fFreq[4] = 0.10;
fFreq[5] = 0.10;
fFreq[6] = 0.18;
fFreq[7] = 0.40;
// 這樣就可以對指定的序列進行哈夫曼編碼
******************************************************************************/
// 分配內存
fFreq = new FLOAT[iColorNum];
// 計算DIB寬度
lWidth = ::DIBWidth(lpDIB);
// 計算DIB高度
lHeight = ::DIBHeight(lpDIB);
// 計算圖像每行的字節數
lLineBytes = WIDTHBYTES(lWidth * 8);
// 重置計數為0
for (i = 0; i < iColorNum; i ++)
{
// 清零
fFreq[i] = 0.0;
}
// 計算各個灰度值的計數(對于非256色位圖,此處給數組fFreq賦值方法將不同)
for (i = 0; i < lHeight; i ++)
{
for (j = 0; j < lWidth; j ++)
{
// 指向圖像指針
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * i + j;
// 計數加1
fFreq[*(lpSrc)] += 1;
}
}
// 計算圖像象素總數
lCountSum = lHeight * lWidth;
// 計算各個灰度值出現的概率
for (i = 0; i < iColorNum; i ++)
{
// 計算概率
fFreq[i] /= (FLOAT)lCountSum;
}
// 計算各個灰度級出現的頻率結束
/*****************************************************************************/
// 創建對話框
CDlgHuffman dlgPara;
// 初始化變量值
dlgPara.m_fFreq = fFreq;
dlgPara.m_iColorNum = iColorNum;
// 顯示對話框
dlgPara.DoModal();
// 解除鎖定
::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
// 恢復光標
EndWaitCursor();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -