数字图像处理领域算法之图像平移

摘自:http://blog.csdn.net/v_july_v/article/details/6227072

我想,图像平移,就不必过多介绍了。无非就是通过坐标的增或减的变化,来达到图像在屏幕上的左移、右移、上移、下移的效果。

    程序实现:

TranslationDIB--该函数用来水平移动DIB图像。函数不会改变图像的大小,移出的部分图像

将截去,空白部分用白色填充。
下面的左移,右移,上移,下移,各自都调用了此TranslationDIB函数。
//图像平移函数。
BOOL WINAPI TranslationDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, LONG

lXOffset, LONG lYOffset)
{
 // 指向源图像的指针
 LPSTR lpSrc;
 // 指向要复制区域的指针
 LPSTR lpDst;
 // 指向复制图像的指针
 LPSTR lpNewDIBBits;
 HLOCAL hNewDIBBits;
 // 象素在新DIB中的坐标
 LONG i;
 LONG j;
 // 象素在源DIB中的坐标
 LONG i0;
 LONG j0;
 // 图像每行的字节数
 LONG lLineBytes;
 // 计算图像每行的字节数
 lLineBytes = WIDTHBYTES(lWidth * 8);

 // 暂时分配内存,以保存新图像
 hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
 if (hNewDIBBits == NULL)
 {
  // 分配内存失败
  return FALSE;
 }
 
 // 锁定内存
 lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
 
 // 每行
 for(i = 0; i < lHeight; i++)
 {
  // 每列
  for(j = 0; j < lWidth; j++)
  {
   // 指向新DIB第i行,第j个象素的指针
   // 注意由于DIB中图像第一行其实保存在最后一行的位置,因此

lpDst
   // 值不是(char *)lpNewDIBBits + lLineBytes * i + j,而是
   // (char *)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) +

j
   lpDst = (char *)lpNewDIBBits + lLineBytes * (lHeight - 1 -

i) + j;
   
   // 计算该象素在源DIB中的坐标
   i0 = i - lXOffset;
   j0 = j - lYOffset;
   
   // 判断是否在源图范围内
   if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 <

lHeight))
   {
    // 指向源DIB第i0行,第j0个象素的指针
    // 同样要注意DIB上下倒置的问题
    lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight

- 1 - i0) + j0;
    
    // 复制象素
    *lpDst = *lpSrc;
   }
   else
   {
    // 对于源图中没有的象素,直接赋值为255
    * ((unsigned char*)lpDst) = 255;
   }
   
  }
 }
 
 // 复制平移后的图像
 memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
 
 // 释放内存
 LocalUnlock(hNewDIBBits);
 LocalFree(hNewDIBBits);
 
 // 返回
 return TRUE;
}

//向左平移,注:在本程序中,移出去的部分,填充以白色。下同。
void CMyDIPView::OnMenuitem32780()
{
 // 平移位图
 // 获取文档
 CMyDIPDoc* pDoc = GetDocument(); 
 // 指向DIB的指针
 LPSTR lpDIB;
 // 指向DIB象素指针
 LPSTR   lpDIBBits;
 // 锁定DIB
 lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
 
 // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的平移,其它的可以类

推)
 if (::DIBNumColors(lpDIB) != 256)
 {
  // 提示用户
  MessageBox("目前只支持256色位图的平移!", "系统提示" ,

MB_ICONINFORMATION | MB_OK);

  // 解除锁定
  ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  
  // 返回
  return;
 }
 
 LONG lXOffset;
 LONG lYOffset;
 // 平移量
 lXOffset = -10;
 lYOffset = 0;

 
 // 更改光标形状
 BeginWaitCursor();

 // 找到DIB图像象素起始位置
 lpDIBBits = ::FindDIBBits(lpDIB);
 
 // 调用TranslationDIB()函数平移DIB
 if (TranslationDIB(lpDIBBits, ::DIBWidth(lpDIB), ::DIBHeight(lpDIB),

lXOffset, lYOffset))
 {
  
  // 设置脏标记
  pDoc->SetModifiedFlag(TRUE);

  // 更新视图
  pDoc->UpdateAllViews(NULL);
 }
 else
 {
  // 提示用户
  MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION |

MB_OK);
 }
 
 // 解除锁定
 ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());

 // 恢复光标
 EndWaitCursor();
}

//向右平移
void CMyDIPView::OnMenuitem32781()
{
 // 平移位图

 // 获取文档
 CMyDIPDoc* pDoc = GetDocument();
 
 // 指向DIB的指针
 LPSTR lpDIB;

 // 指向DIB象素指针
 LPSTR   lpDIBBits;
 
 // 锁定DIB
 lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
 
 // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的平移,其它的可以类

推)
 if (::DIBNumColors(lpDIB) != 256)
 {
  // 提示用户
  MessageBox("目前只支持256色位图的平移!", "系统提示" ,

MB_ICONINFORMATION | MB_OK);

  // 解除锁定
  ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  
  // 返回
  return;
 }
 
 LONG lXOffset;
 LONG lYOffset;
 // 平移量
 lXOffset = 10;
 lYOffset = 0;

 
 // 更改光标形状
 BeginWaitCursor();

 // 找到DIB图像象素起始位置
 lpDIBBits = ::FindDIBBits(lpDIB);
 
 // 调用TranslationDIB()函数平移DIB
 if (TranslationDIB(lpDIBBits, ::DIBWidth(lpDIB), ::DIBHeight(lpDIB),

lXOffset, lYOffset))
 {
  
  // 设置脏标记
  pDoc->SetModifiedFlag(TRUE);

  // 更新视图
  pDoc->UpdateAllViews(NULL);
 }
 else
 {
  // 提示用户
  MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION |

MB_OK);
 }
 
 // 解除锁定
 ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());

 // 恢复光标
 EndWaitCursor();
}

//向上平移
void CMyDIPView::OnMenuitem32779()
{
 // 平移位图

 // 获取文档
 CMyDIPDoc* pDoc = GetDocument();
 
 // 指向DIB的指针
 LPSTR lpDIB;

 // 指向DIB象素指针
 LPSTR   lpDIBBits;
 
 // 锁定DIB
 lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
 
 // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的平移,其它的可以类

推)
 if (::DIBNumColors(lpDIB) != 256)
 {
  // 提示用户
  MessageBox("目前只支持256色位图的平移!", "系统提示" ,

MB_ICONINFORMATION | MB_OK);

  // 解除锁定
  ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  
  // 返回
  return;
 }
 
 LONG lXOffset;
 LONG lYOffset;
 // 平移量
 lXOffset = 0;
 lYOffset = 10;

 
 // 更改光标形状
 BeginWaitCursor();

 // 找到DIB图像象素起始位置
 lpDIBBits = ::FindDIBBits(lpDIB);
 
 // 调用TranslationDIB()函数平移DIB
 if (TranslationDIB(lpDIBBits, ::DIBWidth(lpDIB), ::DIBHeight(lpDIB),

lXOffset, lYOffset))
 {
  
  // 设置脏标记
  pDoc->SetModifiedFlag(TRUE);

  // 更新视图
  pDoc->UpdateAllViews(NULL);
 }
 else
 {
  // 提示用户
  MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION |

MB_OK);
 }
 
 // 解除锁定
 ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());

 // 恢复光标
 EndWaitCursor();
}

//向下平移
void CMyDIPView::OnMenuitem32778()
{
 // 平移位图

 // 获取文档
 CMyDIPDoc* pDoc = GetDocument();
 
 // 指向DIB的指针
 LPSTR lpDIB;

 // 指向DIB象素指针
 LPSTR   lpDIBBits;
 
 // 锁定DIB
 lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
 
 // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的平移,其它的可以类

推)
 if (::DIBNumColors(lpDIB) != 256)
 {
  // 提示用户
  MessageBox("目前只支持256色位图的平移!", "系统提示" ,

MB_ICONINFORMATION | MB_OK);

  // 解除锁定
  ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  
  // 返回
  return;
 }
 
 LONG lXOffset;
 LONG lYOffset;
 // 平移量
 lXOffset = 0;
 lYOffset = -10;

 
 // 更改光标形状
 BeginWaitCursor();

 // 找到DIB图像象素起始位置
 lpDIBBits = ::FindDIBBits(lpDIB);
 
 // 调用TranslationDIB()函数平移DIB
 if (TranslationDIB(lpDIBBits, ::DIBWidth(lpDIB), ::DIBHeight(lpDIB),

lXOffset, lYOffset))
 {
  
  // 设置脏标记
  pDoc->SetModifiedFlag(TRUE);

  // 更新视图
  pDoc->UpdateAllViews(NULL);
 }
 else
 {
  // 提示用户
  MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION |

MB_OK);
 }
 
 // 解除锁定
 ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());

 // 恢复光标
 EndWaitCursor();
}


    变化效果:

posted @ 2013-06-09 16:18  清灵阁主  阅读(1341)  评论(0编辑  收藏  举报