《Visual C++实践与提高—数字图像处理与工程应用篇》第五章学习笔记

发布时间:2024-11-17

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

第五章 图像的几何变换

数字图像平移 图像平移函数

/************************************************************************* * 函数名称:Translation(LPSTR lpSrcStartBits, long lWidth, long lHeight, long lXOffset, long lYOffset,long lLineBytes,long lDstLineBytes) * 函数参数:

* LPSTR lpSrcStartBits,指向源DIB起始像素的指针 * long lWidth,DIB图象的宽度 * long lHeight,DIB图象的高度 * long lXOffset,X方向偏移量 * long lYOffset,Y方向偏移量 * long lLineBytes,DIB图象的行字节数,为4的倍数 * long lDstLineBytes,临时DIB图象的行字节数,为4的倍数 * 函数类型:BOOL

* 函数功能:该函数用来平移DIB图象

************************************************************************/ BOOL Translation(LPSTR lpSrcStartBits, long lWidth, long lHeight, long lXOffset, long lYOffset,long lLineBytes,long lDstLineBytes) {

long i; //行循环变量 long j; //列循环变量

LPSTR lpSrcDIBBits; //指向源像素的指针

LPSTR lpDstDIBBits; //指向临时图象对应像素的指针 LPSTR lpDstStartBits; //指向临时图象对应像素的指针 HLOCAL hDstDIBBits; //临时图象句柄

hDstDIBBits= LocalAlloc(LHND, lWidth * lDstLineBytes);// 分配临时内存 lpDstStartBits= (char * )LocalLock(hDstDIBBits);// 锁定内存 if (hDstDIBBits== NULL)// 判断是否内存分配 return FALSE;// 分配内存失败 for(i = 0; i < lHeight; i++)// 行 { for(j = 0; j < lWidth; j++) // 列 { lpDstDIBBits=(char*)lpDstStartBits+lLineBytes*(lHeight-1-i) +j;// 指向新DIB第i行,第j个像素的指针 if( (j-lYOffset>= 0) && (j-lYOffset< lWidth) && // 像素在源DIB中的坐标j-lXOffset (i-lXOffset>= 0) && (i-lXOffset < lHeight))// 判断是否在源图范围内

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

}

}

}

{

lpSrcDIBBits=(char *)lpSrcStartBits+lLineBytes*(lHeight-1- (i-lXOffset))+(j-lYOffset);// 指向源DIB第i0行,第j0个像素的指针

*lpDstDIBBits= *lpSrcDIBBits;// 复制像素 } else { }

* ((unsigned char*)lpDstDIBBits) = 255;// 源图中没有的像素,赋为255

memcpy(lpSrcStartBits, lpDstStartBits, lLineBytes * lHeight);// 复制图象

LocalUnlock(hDstDIBBits);// 释放内存 LocalFree(hDstDIBBits); return TRUE;

该函数调用函数CDImagePorcess View视图类的 //图像平移

void CDImageProcessView::OnTranslation() { // TODO: Add your command handler code here CDImageProcessDoc* pDoc = GetDocument(); //////////////////////////////////////////////////////////////////////////////////////////////// 回

long lSrcLineBytes; //图象每行的字节数 long lSrcWidth; //图象的宽度和高度 long lSrcHeight; LPSTR lpSrcDib; //指向源图象的指针 LPSTR lpSrcStartBits; //指向源像素的指针 long lDstLineBytes; //新图象每行的字节数

lpSrcDib= (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHObject());// 锁定DIB if (pDoc->m_dib.GetColorNum(lpSrcDib) != 256)// 判断是否是8-bpp位图 { AfxMessageBox("对不起,不是256色位图!");// 警告 ::GlobalUnlock((HGLOBAL) pDoc->GetHObject());// 解除锁定 return; //返回 } //判断是否是8-bpp位图,不是则返

lpSrcStartBits=pDoc->m_dib.GetBits(lpSrcDib); // 找到DIB图象像素起始位置

lSrcWidth= pDoc->m_dib.GetWidth(lpSrcDib); // 获取图象的宽度

lSrcHeight= pDoc->m_dib.GetHeight(lpSrcDib); // 获取图象的高度

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

lSrcLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcWidth * 8); // 计算图象每行的字节数

///////////////////////////////////////////////////////////////////////////////////////////////// 数 }

lDstLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcHeight * 8); // 计算新图象每行的字节

CDlgTran TranPara;// 创建对话框

if (TranPara.DoModal() != IDOK)// 显示对话框,提示用户设定量 return;

int temver=TranPara.m_verOff; int temhor=TranPara.m_horOff;

if (Translation(lpSrcStartBits, lSrcWidth,lSrcHeight,// 调用Translation()函数平移DIB temver,temhor,lSrcLineBytes,lDstLineBytes)) {

pDoc->SetModifiedFlag(TRUE); pDoc->UpdateAllViews(NULL); ::GlobalUnlock((HGLOBAL) pDoc->GetHObject()); } else {

AfxMessageBox(_T("分配内存失败!")); }//警告

// 设置脏标记

// 更新视图

// 解除锁定

数字图像旋转 图像旋转函数

/************************************************************************* * 函数名称:Rotate(LPSTR lpSrcDib, LPSTR lpSrcStartBits,long lWidth, long lHeight, long lLineBytes, WORD palSize, long lDstWidth, long lDstHeight,long lDstLineBytes,float fSina, float fCosa) * 函数参数:

* LPSTR lpSrcDib,指向源DIB的指针

* LPSTR lpSrcStartBits,指向源DIB的起始像素的指针 * long lWidth,源DIB图象宽度 * long lHeight,源DIB图象高度

* long lLineBytes,源DIB图象字节宽度(4的倍数) * WORD palSize,源DIB图象调色板大小 * long lDstWidth,目标图象宽度

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

* long lDstHeight,目标DIB图象高度

* long lDstLineBytes,目标DIB图象行字节数(4的倍数)

* float fSina,旋转角的余弦,说明:为了避免两次求取正余弦,这里作为两个函数参数来用

* float fCosa,旋转角的正弦 * 函数类型:HGLOBAL

* 函数功能:用来旋转DIB图象

************************************************************************/ HGLOBAL Rotate(LPSTR lpSrcDib, LPSTR lpSrcStartBits,long lWidth, long lHeight, long lLineBytes, WORD palSize, long lDstWidth, long lDstHeight,long lDstLineBytes,float fSina, float fCosa) {

float varFloat1; //浮点参数变量1 float varFloat2; //浮点参数变量2 LPSTR lpDstDib; //指向临时图象的指针

long i; //行循环变量 long j; //列循环变量 long i1; //行循环变量 long j1; //列循环变量 LPSTR lpSrcDIBBits; //指向源像素的指针

LPSTR lpDstDIBBits; //指向临时图象对应像素的指针 LPSTR lpDstStartBits; //指向临时图象对应像素的指针

LPBITMAPINFOHEADER lpbmi;// 指向BITMAPINFOHEADER结构的指针 varFloat1= (float) (-0.5 * (lDstWidth - 1) * fCosa - 0.5 * (lDstHeight - 1) * fSina// 将经常用到的两个常数事先求出,以便作为常数使用 + 0.5 * (lDstWidth - 1)); varFloat2= (float) ( 0.5 * (lDstWidth - 1) * fSina - 0.5 * (lDstHeight - 1) * fCosa + 0.5 * (lDstHeight - 1)); HGLOBAL hDIB = (HGLOBAL) ::GlobalAlloc(GHND, lDstLineBytes * lDstHeight + *(LPDWORD)lpSrcDib +palSize);// 分配内存,以保存新DIB if (hDIB == NULL)// 判断是否是有效的DIB对象 { return FALSE;// 不是,则返回 } lpDstDib= (char * )::GlobalLock((HGLOBAL) hDIB);// 锁定内存 memcpy(lpDstDib,lpSrcDib, *(LPDWORD)lpSrcDib +palSize);// 复制DIB信息头和调色板 lpbmi = (LPBITMAPINFOHEADER)lpDstDib;// 获取指针 lpbmi->biHeight=lDstHeight;// 更新DIB中图象的高度和宽度 lpbmi->biWidth =lDstWidth;

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

lpDstStartBits=lpDstDib+ *(LPDWORD)lpDstDib

+palSize;// 求像素起始位置,作用如同::FindDIBBits(gCo.lpSrcDib),这里尝试使用了这种方法,以避免对全局函数的调用

for(i = 0; i < lDstHeight; i++)// 行操作 { for(j = 0; j < lDstWidth; j++)// 列操作 {

lpDstDIBBits= (char *)lpDstStartBits+ lDstLineBytes * (lDstHeight - 1 - i) + j;// 指向新DIB第i行,第j个像素的指针 i1= (long) (-((float) j) * fSina + ((float) i) * fCosa + varFloat2 + 0.5);// 计算该像素在源DIB中的坐标 j1= (long) ( ((float) j) * fCosa + ((float) i) * fSina + varFloat1 + 0.5); if( (j1>= 0) && (j1< lWidth) && (i1>= 0) && (i1< lHeight)) {// 判断是否在源图内 lpSrcDIBBits= (char *)lpSrcStartBits+ lLineBytes * (lHeight - 1 -i1) + j1;// 指向源DIB第i0行,第j0个像素的指针 *lpDstDIBBits= *lpSrcDIBBits;// 复制像素 } else { * ((unsigned char*)lpDstDIBBits) = 255;// 源图中不存在的像素,赋为255 } } } return hDIB; }

该函数调用函数CDImagePorcess View视图类的 //图像旋转

void CDImageProcessView::OnRotation() { // TODO: Add your command handler code here CDImageProcessDoc* pDoc = GetDocument(); //////////////////////////////////////////////////////////////////////////////////////////////// long lSrcLineBytes; //图象每行的字节数 long lSrcWidth; //图象的宽度和高度 long lSrcHeight; LPSTR lpSrcDib; //指向源图象的指针 LPSTR lpSrcStartBits; //指向源像素的指针 long lDstWidth; //临时图象的宽度和高度 long lDstHeight;

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

lpSrcDib= (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHObject());// 锁定DIB if (pDoc->m_dib.GetColorNum(lpSrcDib) != 256)// 判断是否是8-bpp位图 { AfxMessageBox("对不起,不是256色位图!");// 警告 ::GlobalUnlock((HGLOBAL) pDoc->GetHObject());// 解除锁定 return; //返回 } //判断是否是8-bpp位图,不是则返回 lpSrcStartBits=pDoc->m_dib.GetBits(lpSrcDib); // 找到DIB图象像素起始位置

lSrcWidth= pDoc->m_dib.GetWidth(lpSrcDib);

lSrcHeight= pDoc->m_dib.GetHeight(lpSrcDib);

// 获取图象的宽度// 获取图象的高度

lSrcLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcWidth * 8); // 计算图象每行的字节数 long lDstLineBytes;

/////////////////////////////////////////////////////////////////////////////////////////////////

CDlgRot RotPara;// 创建对话框

if(RotPara.DoModal() != IDOK)// 显示对话框,设定旋转角度 { return; }

DWORD palSize=pDoc->m_dib.GetPalSize(lpSrcDib);

float fRotateAngle = (float) AngleToRadian(RotPara.m_rotAngle);// 将旋转角度从度转换到弧度 float fSina = (float) sin((double)fRotateAngle);// 计算旋转角度的正余弦 float fCosa = (float) cos((double)fRotateAngle); float fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4;// 旋转前四个角的坐标(以图象中心为坐标系原点) float fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4;// 旋转后四个角的坐标(以图象中心为坐标系原点) fSrcX1 = (float) (- (lSrcWidth - 1) / 2);// 计算原图的四个角的坐标 fSrcY1 = (float) ( (lSrcHeight - 1) / 2); fSrcX2 = (float) ( (lSrcWidth - 1) / 2); fSrcY2 = (float) ( (lSrcHeight - 1) / 2); fSrcX3 = (float) (- (lSrcWidth - 1) / 2); fSrcY3 = (float) (- (lSrcHeight - 1) / 2); fSrcX4 = (float) ( (lSrcWidth - 1) / 2); fSrcY4 = (float) (- (lSrcHeight - 1) / 2); fDstX1 = fCosa * fSrcX1 + fSina * fSrcY1;// 计算新图四个角的坐标 fDstY1 = -fSina * fSrcX1 + fCosa * fSrcY1;

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

fDstX2 = fCosa * fSrcX2 + fSina * fSrcY2; fDstY2 = -fSina * fSrcX2 + fCosa * fSrcY2; fDstX3 = fCosa * fSrcX3 + fSina * fSrcY3; fDstY3 = -fSina * fSrcX3 + fCosa * fSrcY3; fDstX4 = fCosa * fSrcX4 + fSina * fSrcY4; fDstY4 = -fSina * fSrcX4 + fCosa * fSrcY4; lDstWidth= (long) ( max( fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2) ) + 0.5);// 计算旋转后的图象实际宽度 lDstLineBytes=pDoc->m_dib.GetReqByteWidth(lDstWidth * 8);// 计算新图象每行的字节数 lDstHeight= (long) ( max( fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2) ) + 0.5);// 计算旋转后的图象高度 }

HGLOBAL hDstDIB = NULL;// 创建新DIB

hDstDIB = (HGLOBAL) Rotate(lpSrcDib,lpSrcStartBits,lSrcWidth,lSrcHeight,lSrcLineBytes, palSize,lDstWidth,lDstHeight,lDstLineBytes,fSina,fCosa);// 调用Rotate()函数旋转DIB

if(hDstDIB != NULL)// 判断旋转是否成功 {

pDoc->UpdateObject(hDstDIB);// 替换DIB,同时释放旧DIB对象 pDoc->SetDib();// 更新DIB大小和调色板 pDoc->SetModifiedFlag(TRUE); // 设置脏标记

// 更新视图

pDoc->UpdateAllViews(NULL); ::GlobalUnlock((HGLOBAL) pDoc->GetHObject()); } else { AfxMessageBox(_T("分配内存失败!")); }// 警告

// 解除锁定

数字图像缩放 图像缩放函数

/************************************************************************* * 函数名称:Zoom(LPSTR lpSrcDib, LPSTR lpSrcStartBits,long lWidth, long lHeight, long lLineBytes, WORD palSize, long lDstWidth, long lDstHeight,long lDstLineBytes,float fXZoomRatio, float fYZoomRatio) * 函数参数:

* LPSTR lpSrcDib,指向源DIB的指针

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

* LPSTR lpSrcStartBits,指向源DIB的起始像素的指针 * long lWidth,源DIB图象宽度 * long lHeight,源DIB图象高度

* long lLineBytes,源DIB图象字节宽度(4的倍数) * WORD palSize,源DIB图象调色板大小 * long lDstWidth,目标图象宽度

* long lDstHeight,目标DIB图象高度

* long lDstLineBytes,目标DIB图象行字节数(4的倍数) * float fhorRatio,水平缩放比率 * float fverRatio,垂直缩放比率 * 函数类型:HGLOBAL

* 函数功能:用来缩放DIB图象

************************************************************************/

HGLOBAL Zoom(LPSTR lpSrcDib, LPSTR lpSrcStartBits,long lWidth, long lHeight, long lLineBytes, WORD palSize,long lDstWidth,long lDstLineBytes,long lDstHeight, float fhorRatio,float fverRatio) { LPSTR lpDstDib; //指向临时图象的指针 long i; //行循环变量 long j; //列循环变量 long i1; //行循环变量 long j1; //列循环变量 LPSTR lpSrcDIBBits; //指向源像素的指针 LPSTR lpDstDIBBits; //指向临时图象对应像素的指针 LPSTR lpDstStartBits; //指向临时图象对应像素的指针 LPBITMAPINFOHEADER lpbmi;// 指向BITMAPINFO结构的指针 // 分配内存,以保存缩放后的DIB HGLOBAL hDIB = (HGLOBAL) ::GlobalAlloc(GHND, lDstLineBytes* lDstHeight + *(LPDWORD)lpSrcDib +palSize); if (hDIB == NULL)// 判断是否是有效的DIB对象 { return FALSE;// 不是,则返回 } lpDstDib= (char * )::GlobalLock((HGLOBAL) hDIB);// 锁定内存 memcpy(lpDstDib, lpSrcDib, *(LPDWORD)lpSrcDib +palSize);// 复制DIB信息头和调色板 lpDstStartBits=lpDstDib+ *(LPDWORD)lpDstDib// 找到新DIB像素起始位置 +palSize;// 求像素起始位置,作用如同::FindDIBBits(lpSrcDib),这里尝试使用了这种方法,以避免对全局函数的调用

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

lpbmi = (LPBITMAPINFOHEADER)lpDstDib;// 获取指针

lpbmi->biWidth = lDstWidth;// 更新DIB中图象的高度和宽度 lpbmi->biHeight =lDstHeight;

for(i = 0; i < lDstHeight; i++)// 行操作 { for(j = 0; j < lDstWidth; j++)// 列操作 {

// 指向新DIB第i行,第j个像素的指针

lpDstDIBBits= (char *)lpDstStartBits + lDstLineBytes * (lDstHeight-1-i)+j; i1= (long) (i / fverRatio + 0.5);// 计算该像素在源DIB中的坐标 j1= (long) (j / fhorRatio + 0.5);

if( (j1>= 0) && (j1< lWidth) && (i1>= 0) && (i1< lHeight))

{// 判断是否在源图内 lpSrcDIBBits= (char *)lpSrcStartBits+ lLineBytes * (lHeight - 1 -i1) + j1;// 指向源DIB第i行,第j个像素的指针 *lpDstDIBBits= *lpSrcDIBBits;// 复制像素 } else { * ((unsigned char*)lpDstDIBBits) = 255;// 源图中不存在的像素,赋为255 } } } return hDIB; }

该函数调用函数CDImagePorcess View视图类的 //图像缩放

void CDImageProcessView::OnZoom() { // TODO: Add your command handler code here CDImageProcessDoc* pDoc = GetDocument(); //////////////////////////////////////////////////////////////////////////////////////////////// long lSrcLineBytes; //图象每行的字节数 long lSrcWidth; //图象的宽度和高度 long lSrcHeight; LPSTR lpSrcDib; //指向源图象的指针 LPSTR lpSrcStartBits; //指向源像素的指针 long lDstWidth; //临时图象的宽度和高度 long lDstHeight;

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

long lDstLineBytes;

lpSrcDib= (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHObject());// 锁定DIB if (pDoc->m_dib.GetColorNum(lpSrcDib) != 256)// 判断是否是8-bpp位图 { }

AfxMessageBox("对不起,不是256色位图!");// 警告 ::GlobalUnlock((HGLOBAL) pDoc->GetHObject());// 解除锁定 return; //返回

lpSrcStartBits=pDoc->m_dib.GetBits(lpSrcDib);

lSrcWidth= pDoc->m_dib.GetWidth(lpSrcDib);

// 找到DIB图象像素起始位置

// 获取图象的宽度// 获取图象的高度

lSrcHeight= pDoc->m_dib.GetHeight(lpSrcDib);

lSrcLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcWidth * 8); // 计算图象每行的字节数

///////////////////////////////////////////////////////////////////////////////////////////////// DWORD palSize=pDoc->m_dib.GetPalSize(lpSrcDib); CDlgZoom ZoomPara;// 创建对话框,设定平移量 if (ZoomPara.DoModal() != IDOK) { return; }

float fX = ZoomPara.m_horZoom;// 获取设定的平移量,缩放比率 float fY = ZoomPara.m_verZoom;

lDstWidth= (long) (lSrcWidth*fX + 0.5);// 计算缩放后的图象实际宽度,加0.5是由于强制类型转换时不四舍五入,而是直接截去小数部分 lDstLineBytes=pDoc->m_dib.GetReqByteWidth(lDstWidth * 8); //转换后图象应有的行字节数,为4的倍数 lDstHeight= (long) (lSrcHeight * fY + 0.5);// 计算缩放后的图象高度 HGLOBAL hDstDIB = NULL;// 创建新DIB hDstDIB = (HGLOBAL) Zoom(lpSrcDib,lpSrcStartBits,lSrcWidth,lSrcHeight, lSrcLineBytes,palSize,lDstWidth,lDstLineBytes,lDstHeight,fX, fY);// 调用Zoom()函数转置DIB if(hDstDIB != NULL)// 判断旋转是否成功 { pDoc->UpdateObject(hDstDIB);// 替换DIB,同时释放旧DIB对象 pDoc->SetDib();// 更新DIB大小和调色板 pDoc->SetModifiedFlag(TRUE); // 设置脏标记

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

pDoc->UpdateAllViews(NULL); // 更新视图

::GlobalUnlock((HGLOBAL) pDoc->GetHObject());

// 解除锁定

} else { AfxMessageBox(_T("分配内存失败!")); } // 警告

}

数字图像转置 图像转置函数

/************************************************************************* * 函数名称:

* Transpose(LPSTR lpSrcDib,LPSTR lpDibBits,long lWidth,long lHeight, long lLineBytes,long lDstLineBytes) * 函数参数:

* LPSTR lpSrcDib,指向源DIB的指针

LPSTR lpSrcStartBits,指向DIB起始像素的指针 long lWidth,DIB图象的宽度 long lHeight,DIB图象的高度 long lLineBytes,DIB图象的行字节数,为4的倍数 long lDstLineBytes,临时DIB图象的行字节数,为4的倍数 * 函数类型:BOOL

* 函数功能:该函数用来转置DIB图象

************************************************************************/

BOOL Transpose(LPSTR lpSrcDib,LPSTR lpSrcStartBits,long lWidth,long lHeight, long lLineBytes,long lDstLineBytes) { long i; //行循环变量 long j; //列循环变量 LPSTR lpSrcDIBBits; //指向源像素的指针 LPSTR lpDstDIBBits; //指向临时图象对应像素的指针 LPSTR lpDstStartBits; //指向临时图象对应像素的指针 HLOCAL hDstDIBBits; //临时图象句柄 LPBITMAPINFOHEADER lpbmi; // 指BITMAPINFOHEADER结构的指针 lpbmi = (LPBITMAPINFOHEADER)lpSrcDib; hDstDIBBits= LocalAlloc(LHND, lWidth * lDstLineBytes);// 分配临时内存 if (hDstDIBBits== NULL) // 判断是否内存分配

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

{

// 分配内存失败

return FALSE; }

lpDstStartBits= (char * )LocalLock(hDstDIBBits); for(i = 0; i < lHeight; i++) { for(j = 0; j < lWidth; j++) {

// 锁定内存

// 针对图象每行进行操作

// 针对图象每列进行操作

lpSrcDIBBits= (char *)lpSrcStartBits + lLineBytes * (lHeight - 1 - i) + j;// 指向源DIB第i行,第j个像素的指针 lpDstDIBBits= (char *)lpDstStartBits + lDstLineBytes * (lWidth - 1 - j) + i;// 指向转置DIB第j行,第i个像素的指针 *(lpDstDIBBits)= *(lpSrcDIBBits); // 复制像素 } } memcpy(lpSrcStartBits, lpDstStartBits, lWidth * lDstLineBytes);// 复制转置后的图象 lpbmi->biWidth = lHeight; lpbmi->biHeight = lWidth; LocalUnlock(hDstDIBBits); // 释放内存 LocalFree(hDstDIBBits); return TRUE; // 返回 }

该函数调用函数CDImagePorcess View视图类的 //图像转置

void CDImageProcessView::OnTranspose() { // TODO: Add your command handler code here CDImageProcessDoc* pDoc = GetDocument();

////////////////////////////////////////////////////////////////////////////////////////////////

long lSrcLineBytes; //图象每行的字节数 long lSrcWidth; //图象的宽度和高度 long lSrcHeight;

LPSTR lpSrcDib; //指向源图象的指针 LPSTR lpSrcStartBits; //指向源像素的指针 long lDstLineBytes; //新图象每行的字节数

lpSrcDib= (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHObject());// 锁定DIB if (pDoc->m_dib.GetColorNum(lpSrcDib) != 256)// 判断是否是8-bpp位图 { AfxMessageBox("对不起,不是256色位图!");// 警告 ::GlobalUnlock((HGLOBAL) pDoc->GetHObject());// 解除锁定 return; //返回

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

}

lpSrcStartBits=pDoc->m_dib.GetBits(lpSrcDib);

lSrcWidth= pDoc->m_dib.GetWidth(lpSrcDib);

lSrcHeight= pDoc->m_dib.GetHeight(lpSrcDib);

//判断是否是8-bpp位图,不是则返

// 找到DIB图象像素起始位置

// 获取图象的宽度// 获取图象的高度

lSrcLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcWidth * 8); // 计算图象每行的字节数

///////////////////////////////////////////////////////////////////////////////////////////////// lDstLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcHeight * 8); // 计算新图象每行的字节数 if (Transpose(lpSrcDib,lpSrcStartBits,lSrcWidth, }

{

lSrcHeight,lSrcLineBytes,lDstLineBytes)) // 调用Transpose()函数转置DIB

pDoc->SetDib(); // 更新DIB大小和调色板

pDoc->SetModifiedFlag(TRUE);

// 设置脏标记// 更新视图

pDoc->UpdateAllViews(NULL);

::GlobalUnlock((HGLOBAL) pDoc->GetHObject()); } else { AfxMessageBox(_T("分配内存失败!")); // 警告 }

// 解除锁定

数字图像垂直镜像 图像垂直镜像函数

/************************************************************************* * 函数名称:Mirrorchuizhi(LPSTR lpSrcStartBits, long lWidth, long lHeight,long lLineBytes) * 函数参数:

LPSTR lpSrcStartBits,指向DIB起始像素的指针 long lWidth,DIB图象的宽度 long lHeight,DIB图象的高度 long lLineBytes,DIB图象的行字节数,为4的倍数 * 函数类型:BOOL

* 函数功能:该函数用来镜像DIB图象,本程序实现垂直镜像

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

************************************************************************/

BOOL Mirrorchuizhi(LPSTR lpSrcStartBits, long lWidth, long lHeight,long lLineBytes) {

long i; //行循环变量 long j; //列循环变量

LPSTR lpSrcDIBBits; //指向源像素的指针

LPSTR lpDstDIBBits; //指向临时图象对应像素的指针 HLOCAL hDstDIBBits; //临时图象句柄

LPSTR lpBits; // 指向中间像素的指针,当复制图象时,提供临时的像素内存空间 hDstDIBBits= LocalAlloc(LHND, lLineBytes);// 分配临时内存保存行图象 if (hDstDIBBits == NULL) {

return FALSE; // 分配内存失败 } lpDstDIBBits= (char * )LocalLock(hDstDIBBits);// 锁定 for(i = 0; i < lHeight/2; i++)// 垂直镜像,针对图象每行进行操作 { lpSrcDIBBits= (char *)lpSrcStartBits + lLineBytes * i;// 指向倒数第i行像素起点的指针 lpBits= (char *)lpSrcStartBits + lLineBytes * (lHeight-i - 1) ;// 指向第i行像素起点的指针 memcpy(lpDstDIBBits,lpBits,lLineBytes);//备份一行,宽度为lWidth memcpy(lpBits,lpSrcDIBBits,lLineBytes);//将倒数第i行像素复制到第i行 memcpy(lpSrcDIBBits,lpDstDIBBits,lLineBytes);//将第i行像素复制到倒数第i行 } }

LocalUnlock(hDstDIBBits);// 释放内存 LocalFree(hDstDIBBits); return TRUE;

数字图像水平镜像 图像水平镜像函数

/************************************************************************* * 函数名称:Mirror(LPSTR lpSrcStartBits, long lWidth, long lHeight,long lLineBytes) * 函数参数:

LPSTR lpSrcStartBits,指向DIB起始像素的指针 long lWidth,DIB图象的宽度 long lHeight,DIB图象的高度 long lLineBytes,DIB图象的行字节数,为4的倍数 * 函数类型:BOOL

* 函数功能:该函数用来镜像DIB图象,本程序只实现了水平镜像,垂直镜像的原理书中也

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

谈到。 很容易实现

************************************************************************/

BOOL Mirror(LPSTR lpSrcStartBits, long lWidth, long lHeight,long lLineBytes) {

long i; //行循环变量 long j; //列循环变量

LPSTR lpSrcDIBBits; //指向源像素的指针

LPSTR lpDstDIBBits; //指向临时图象对应像素的指针 HLOCAL hDstDIBBits; //临时图象句柄

LPSTR lpBits; // 指向中间像素的指针,当复制图象时,提供临时的像素内存空间 hDstDIBBits= LocalAlloc(LHND, lLineBytes);// 分配临时内存保存行图象 if (hDstDIBBits == NULL) { }

return FALSE;

// 分配内存失败

lpDstDIBBits= (char * )LocalLock(hDstDIBBits);// 锁定

for(i = 0; i < lHeight; i++)// 水平镜像,针对图象每行进行操作 { for(j = 0; j < lWidth / 2; j++)// 针对每行图象左半部分进行操作 { lpSrcDIBBits= (char *)lpSrcStartBits + lLineBytes * i + j;// 指向倒数第i行,第j个像素的指针 lpBits= (char *)lpSrcStartBits + lLineBytes * (i + 1) - j;// 指向倒数第i+1行,倒数第j个像素的指针 *lpDstDIBBits=*lpBits;//保存中间像素 *lpBits = *lpSrcDIBBits;// 将倒数第i行,第j个像素复制到倒数第i行,倒数第j个像素 *lpSrcDIBBits=*lpDstDIBBits;// 将倒数第i行,倒数第j个像素复制到倒数第i行,第j个像素 } } LocalUnlock(hDstDIBBits);// 释放内存 LocalFree(hDstDIBBits); return TRUE; }

该函数调用函数CDImagePorcess View视图类的 //水平镜像

void CDImageProcessView::OnMirror() { CDImageProcessDoc* pDoc = GetDocument(); // 获取文档 ////////////////////////////////////////////////////////////////////////////////////////////////

这是本人学习《Visual C++实践与提高—数字图像处理与工程应用篇》这本书时做的笔记。该书由高守传 姚领田等编著。中国铁道出版社出版

long lSrcWidth; //图象的宽度和高度 long lSrcHeight; LPSTR lpSrcDib; //指向源图象的指针 LPSTR lpSrcStartBits; //指向源像素的指针

lpSrcDib= (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHObject());// 锁定DIB if (pDoc->m_dib.GetColorNum(lpSrcDib) != 256)// 判断是否是8-bpp位图 {

AfxMessageBox("对不起,不是256色位图!");// 警告 ::GlobalUnlock((HGLOBAL) pDoc->GetHObject());// 解除锁定 return; //返回 } //判断是否是8-bpp位图,不是则返

lpSrcStartBits=pDoc->m_dib.GetBits(lpSrcDib); // 找到DIB图象像素起始位置

lSrcWidth= pDoc->m_dib.GetWidth(lpSrcDib); // 获取图象的宽度

lSrcHeight= pDoc->m_dib.GetHeight(lpSrcDib); // 获取图象的高度 lSrcLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcWidth * 8); // 计算图象每行的字节数

///////////////////////////////////////////////////////////////////////////////////////////////// if (Mirror(lpSrcStartBits,lSrcWidth, lSrcHeight,lSrcLineBytes))// 调用Mirror()函数水平镜像DIB {

pDoc->SetModifiedFlag(TRUE);

// 设置脏标记

pDoc->UpdateAllViews(NULL); // 更新视图 ::GlobalUnlock((HGLOBAL) pDoc->GetHObject()); // 解除锁定 } else { AfxMessageBox(_T("分配内存失败!")); }// 警告 }

//垂直镜像

void CDImageProcessView::OnMirror() { CDImageProcessDoc* pDoc = GetDocument(); // 获取文档 ////////////////////////////////////////////////////////////////////////////////////////////////

《Visual C++实践与提高—数字图像处理与工程应用篇》第五章学习笔记.doc 将本文的Word文档下载到电脑

    精彩图片

    热门精选

    大家正在看

    × 游客快捷下载通道(下载后可以自由复制和排版)

    限时特价:7 元/份 原价:20元

    支付方式:

    开通VIP包月会员 特价:29元/月

    注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
    微信:fanwen365 QQ:370150219