zoukankan      html  css  js  c++  java
  • 数字图像处理领域算法之图像平移

    摘自: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();
    }


        变化效果:

  • 相关阅读:
    Leetcode: Reverse Integer
    Leetcode: Two Sum
    Leetcode: Path Sum
    make distclean
    makefile 中 foreach
    nor flash 和 nand flash
    端口(port)的安全模式(security mode)
    单片机入门(二)
    单片机入门(一)
    kworker
  • 原文地址:https://www.cnblogs.com/LCGIS/p/3129402.html
Copyright © 2011-2022 走看看