CString listname;
// 控件ListCtrl的ITEM LV_ITEM codingItem; // 保存控件ListCtrl中添加的ITEM编号 int nItem2View;
// 设置CListCtrl控件样式
m_codinglist.ModifyStyle(LVS_TYPEMASK, LVS_REPORT); // 给List控件添加Header
m_codinglist.InsertColumn(0, \像素灰度\ m_codinglist.InsertColumn(1, \灰度概率\ m_codinglist.InsertColumn(2, \编码码字\ m_codinglist.InsertColumn(3, \码字长度\ // 设置样式为文本
codingItem.mask = LVIF_TEXT;
// 添加显示
for (i = 0; i < graygrade; i ++) { // 第一列显示 codingItem.iItem = m_codinglist.GetItemCount(); listname.Format(\ codingItem.iSubItem = 0; //显示像素灰度
codingItem.pszText= (LPTSTR)(LPCTSTR)listname; nItem2View = m_codinglist.InsertItem(&codingItem); codingItem.iItem = nItem2View; // 第二列显示
codingItem.iSubItem = 1; listname.Format(\
codingItem.pszText = (LPTSTR)(LPCTSTR)listname; m_codinglist.SetItem(&codingItem); // 第三列显示
codingItem.iSubItem = 2;
codingItem.pszText = (LPTSTR)(LPCTSTR)m_strCode[i]; m_codinglist.SetItem(&codingItem); // 第四列显示
codingItem.iSubItem = 3;
listname.Format(\ codingItem.pszText = (LPTSTR)(LPCTSTR)listname; m_codinglist.SetItem(&codingItem); }
delete turn; //内存释放 delete temp;
delete bFinished;
return TRUE;
第 21 页 共 32 页
}
5.2.2 视图类处理函数On Shannon Coding()函数
关于函数的调用部分,在图像处理的主窗口的菜单栏“图像编码”下添加“香农-范诺编码”项,对应的处理函数是CDImageProcessView视图类中的OnShannoncoding()函数。OnShannoncoding()函数实现了图像灰度概率的计算和编码对话框的调用,具体代码如下:
void CDImageProcessView::OnShannoncoding() { // 获取文档
CDImageProcessDoc* pDoc = GetDocument(); //指向源图像的指针 unsigned char* lpSrc;
// 指向DIB的指针 LPSTR lpDIB; // 指向DIB象素指针
LPSTR lpDIBBits; //图像灰度等级数
int graygrade;
// 锁定DIB
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHObject()); // 找到DIB图像象素起始位置
lpDIBBits = pDoc->m_dib.GetBits(lpDIB); // 判断是否是8位位图
if (pDoc->m_dib.GetColorNum(lpDIB) != 256)
{ // 提示用户 MessageBox(\目前只支持256色位图!\系统提示\ }
MB_ICONINFORMATION | MB_OK);
::GlobalUnlock((HGLOBAL) pDoc->GetHObject()); // 解除锁定 return; // 返回
//灰度等级数为256
graygrade=pDoc->m_dib.GetColorNum(lpDIB); //各灰度等级出现的概率
double * grayfreq;
//图像宽度
int width; //图像高度
int height;
width=pDoc->m_dib.GetWidth(lpDIB); height=pDoc->m_dib.GetHeight(lpDIB); // 更改光标形状
BeginWaitCursor();
第 22 页 共 32 页
//开始计算各个灰度级出现的概率,如果需要对指定的序列进行哈夫曼编码, //只要将这一步改成给各个灰度级概率赋值即可
grayfreq = new double[graygrade]; // 分配内存 int graySum; //像素数目 int i; //循环变量 int j; //循环变量
// 计算图象象素总数
graySum = width * height;
{ // 赋零值 grayfreq[i] = 0.0; }
for (i = 0; i < graygrade; i ++)
// 计算各个灰度值的计数
for (i = 0; i < height; i ++) {
for (j = 0; j < width; j ++)
{ // 指向图象指针 lpSrc = (unsigned char*)lpDIBBits + width * i + j; // 相应的灰度计数加1 grayfreq[*(lpSrc)] = grayfreq[*(lpSrc)] + 1; }
}
for (i = 0; i < graygrade; i ++) { // 计算各个灰度值出现的概率 grayfreq[i] = grayfreq[i] / (double)graySum; }
CShannonCoding coding; // 创建对话框 coding.grayfreq = grayfreq; // 初始化变量值 coding.graygrade = graygrade;
coding.DoModal(); // 显示对话框 EndWaitCursor(); // 恢复光标 }
5.3 行程编码
5.3.1 行程编码算法实现
函数PCXCoding()将指定的256色DIB对象保存为256色PCX文件。参数LPSTR lpDIBBits是指向DIB对象像素的指针; 参数LONG ImageWidth 是源图像宽度(像素数,必须是4的倍数);参数LONG ImageHeight是源图像高度(像素数);参数CFile& file是要保存的文件。
BOOL PCXCoding(LPSTR lpDIBBits,LONG ImageWidth,LONG ImageHeight,CFile& file)
第 23 页 共 32 页
{ typedef struct{ char manufacturer; char version; char encoding; char bits_per_pixel; WORD xmin,ymin; WORD xmax,ymax; WORD hres; WORD vres; char palette[48]; char reserved; char colour_planes; WORD bytes_per_line; WORD palette_type;
char filler[58];
}PCXHEAD;
int i; int j; //中间变量
BYTE bChar1; //中间变量
BYTE bChar2; //指向源图像像素的指针
BYTE * lpSrc; //指向编码后图像数据的指针
BYTE * lpDst; //重复像素计数
int iCount; //缓冲区已使用的字节数
DWORD dwBuffUsed; //PCX文件头
PCXHEAD pcxHeadr; //PCX标志码
pcxHeadr.manufacturer= 0x0A; //PCX版本号
pcxHeadr.version =5; //PCX编码方式(1表示RLE编码)
pcxHeadr.encoding =1; //像素位数(256色为8位)
pcxHeadr.bits_per_pixel =8; //图像相对于屏幕的左上角X坐标
pcxHeadr.xmin=0; //图像相对于屏幕的左上角Y坐标
第 24 页 共 32 页
pcxHeadr.ymin=0; //图像相对于屏幕的右下角X坐标
pcxHeadr.xmax=ImageWidth-1; //图像相对于屏幕的右下角Y坐标
pcxHeadr.ymax=ImageHeight-1; //图像的水平分辨率
pcxHeadr.hres = ImageWidth; //图像的垂直分辨率
pcxHeadr.vres = ImageHeight; for(i = 0 ; i < 48 ; i++)
{ //调色板数据(对于256色PCX无意义,直接赋值为0) pcxHeadr.palette[i] = 0; }
//保留域 设定为0
pcxHeadr.reserved =0; //图像色彩平面数目对于256色PCX设为1 pcxHeadr.colour_planes=1; //图像的宽度(字节为单位)必须为偶数 pcxHeadr.bytes_per_line = ImageWidth;
//图像调色板的类型,1表示彩色或者单色图像,2表示图像是灰度图 pcxHeadr.palette_type = 1; for(i = 0; i < 54; i ++) {
pcxHeadr.filler[i]= 0; }
//写入头文件
file.Write((LPSTR)&pcxHeadr,sizeof(PCXHEAD)); //分配内存以保存编码结果
lpDst = new BYTE[ImageHeight * ImageWidth*2]; //指明当前已经用了多少缓冲区(字节数) dwBuffUsed = 0; for(i=0;i { //指向DIB第i行,第0个像素的指针 lpSrc = (BYTE *)lpDIBBits + ImageWidth *(ImageHeight -1 -i); //给bChar1赋值 bChar1 = *lpSrc; //设置iCount为1 iCount = 1; for(j =1; j< ImageWidth; j++) { lpSrc++; bChar2 = *lpSrc; if((bChar1==bChar2)&&(iCount<63)) iCount++; 第 25 页 共 32 页