?? geotrans.cpp
字號(hào):
/************************************************************************** * 文件名:GeoTrans.cpp * * 圖像幾何變換API函數(shù)庫: * * TranslationDIB1() - 圖像平移 * TranslationDIB() - 圖像平移 * MirrorDIB() - 圖像鏡像 * TransposeDIB() - 圖像轉(zhuǎn)置 * ZoomDIB() - 圖像縮放 * RotateDIB() - 圖像旋轉(zhuǎn) * *************************************************************************/#include "stdafx.h"#include "geotrans.h"#include "DIBAPI.h"#include <math.h>#include <direct.h>/************************************************************************* * * TranslationDIB1() * * 參數(shù): * LPSTR lpDIBBits - 指向源DIB圖像指針 * LONG lWidth - 源圖像寬度(象素?cái)?shù)) * LONG lHeight - 源圖像高度(象素?cái)?shù)) * LONG lXOffset - X軸平移量(象素?cái)?shù)) * LONG lYOffset - Y軸平移量(象素?cái)?shù)) * * 返回值: * BOOL - 平移成功返回TRUE,否則返回FALSE。 * * 說明: * 該函數(shù)用來水平移動(dòng)DIB圖像。函數(shù)不會(huì)改變圖像的大小,移出的部分圖像 * 將截去,空白部分用白色填充。 * ************************************************************************/BOOL WINAPI TranslationDIB1(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, LONG lXOffset, LONG lYOffset){ // 指向源圖像的指針 LPSTR lpSrc; // 指向要復(fù)制區(qū)域的指針 LPSTR lpDst; // 指向復(fù)制圖像的指針 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; // 象素在新DIB中的坐標(biāo) LONG i; LONG j; // 象素在源DIB中的坐標(biāo) LONG i0; LONG j0; // 圖像每行的字節(jié)數(shù) LONG lLineBytes; // 計(jì)算圖像每行的字節(jié)數(shù) lLineBytes = WIDTHBYTES(lWidth * 8); // 暫時(shí)分配內(nèi)存,以保存新圖像 hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); if (hNewDIBBits == NULL) { // 分配內(nèi)存失敗 return FALSE; } // 鎖定內(nèi)存 lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 每行 for(i = 0; i < lHeight; i++) { // 每列 for(j = 0; j < lWidth; j++) { // 指向新DIB第i行,第j個(gè)象素的指針 // 注意由于DIB中圖像第一行其實(shí)保存在最后一行的位置,因此lpDst // 值不是(char *)lpNewDIBBits + lLineBytes * i + j,而是 // (char *)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j lpDst = (char *)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j; // 計(jì)算該象素在源DIB中的坐標(biāo) i0 = i - lXOffset; j0 = j - lYOffset; // 判斷是否在源圖范圍內(nèi) if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)) { // 指向源DIB第i0行,第j0個(gè)象素的指針 // 同樣要注意DIB上下倒置的問題 lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0; // 復(fù)制象素 *lpDst = *lpSrc; } else { // 對(duì)于源圖中沒有的象素,直接賦值為255 * ((unsigned char*)lpDst) = 255; } } } // 復(fù)制平移后的圖像 memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); // 釋放內(nèi)存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); // 返回 return TRUE;}/************************************************************************* * * 函數(shù)名稱: * TranslationDIB() * * 參數(shù): * LPSTR lpDIBBits - 指向源DIB圖像指針 * LONG lWidth - 源圖像寬度(象素?cái)?shù)) * LONG lHeight - 源圖像高度(象素?cái)?shù)) * LONG lXOffset - X軸平移量(象素?cái)?shù)) * LONG lYOffset - Y軸平移量(象素?cái)?shù)) * * 返回值: * BOOL - 平移成功返回TRUE,否則返回FALSE。 * * 說明: * 該函數(shù)用來水平移動(dòng)DIB圖像。函數(shù)不會(huì)改變圖像的大小,移出的部分圖像 * 將截去,空白部分用白色填充。 * ************************************************************************/BOOL WINAPI TranslationDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, LONG lXOffset, LONG lYOffset){ // 平移后剩余圖像在源圖像中的位置(矩形區(qū)域) CRect rectSrc; // 平移后剩余圖像在新圖像中的位置(矩形區(qū)域) CRect rectDst; // 指向源圖像的指針 LPSTR lpSrc; // 指向要復(fù)制區(qū)域的指針 LPSTR lpDst; // 指向復(fù)制圖像的指針 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; // 指明圖像是否全部移去可視區(qū)間 BOOL bVisible; // 循環(huán)變量 LONG i; // 圖像每行的字節(jié)數(shù) LONG lLineBytes; // 計(jì)算圖像每行的字節(jié)數(shù) lLineBytes = WIDTHBYTES(lWidth * 8); // 賦初值 bVisible = TRUE; // 計(jì)算rectSrc和rectDst的X坐標(biāo) if (lXOffset <= -lWidth) { // X軸方向全部移出可視區(qū)域 bVisible = FALSE; } else if (lXOffset <= 0) { // 移動(dòng)后,有圖區(qū)域左上角X坐標(biāo)為0 rectDst.left = 0; // 移動(dòng)后,有圖區(qū)域右下角X坐標(biāo)為lWidth - |lXOffset| = lWidth + lXOffset rectDst.right = lWidth + lXOffset; } else if (lXOffset < lWidth) { // 移動(dòng)后,有圖區(qū)域左上角X坐標(biāo)為lXOffset rectDst.left = lXOffset; // 移動(dòng)后,有圖區(qū)域右下角X坐標(biāo)為lWidth rectDst.right = lWidth; } else { // X軸方向全部移出可視區(qū)域 bVisible = FALSE; } // 平移后剩余圖像在源圖像中的X坐標(biāo) rectSrc.left = rectDst.left - lXOffset; rectSrc.right = rectDst.right - lXOffset; // 計(jì)算rectSrc和rectDst的Y坐標(biāo) if (lYOffset <= -lHeight) { // Y軸方向全部移出可視區(qū)域 bVisible = FALSE; } else if (lYOffset <= 0) { // 移動(dòng)后,有圖區(qū)域左上角Y坐標(biāo)為0 rectDst.top = 0; // 移動(dòng)后,有圖區(qū)域右下角Y坐標(biāo)為lHeight - |lYOffset| = lHeight + lYOffset rectDst.bottom = lHeight + lYOffset; } else if (lYOffset < lHeight) { // 移動(dòng)后,有圖區(qū)域左上角Y坐標(biāo)為lYOffset rectDst.top = lYOffset; // 移動(dòng)后,有圖區(qū)域右下角Y坐標(biāo)為lHeight rectDst.bottom = lHeight; } else { // X軸方向全部移出可視區(qū)域 bVisible = FALSE; } // 平移后剩余圖像在源圖像中的Y坐標(biāo) rectSrc.top = rectDst.top - lYOffset; rectSrc.bottom = rectDst.bottom - lYOffset; // 暫時(shí)分配內(nèi)存,以保存新圖像 hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); if (hNewDIBBits == NULL) { // 分配內(nèi)存失敗 return FALSE; } // 鎖定內(nèi)存 lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 初始化新分配的內(nèi)存,設(shè)定初始值為255 lpDst = (char *)lpNewDIBBits; memset(lpDst, (BYTE)255, lLineBytes * lHeight); // 如果有部分圖像可見 if (bVisible) { // 平移圖像 for(i = 0; i < (rectSrc.bottom - rectSrc.top); i++) { // 要復(fù)制區(qū)域的起點(diǎn),注意由于DIB圖像內(nèi)容是上下倒置的,第一行內(nèi)容是保存在最后 // 一行,因此復(fù)制區(qū)域的起點(diǎn)不是lpDIBBits + lLineBytes * (i + rectSrc.top) + // rectSrc.left,而是 lpDIBBits + lLineBytes * (lHeight - i - rectSrc.top - 1) + // rectSrc.left。 lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - i - rectSrc.top - 1) + rectSrc.left; // 要目標(biāo)區(qū)域的起點(diǎn) // 同樣注意上下倒置的問題。 lpDst = (char *)lpNewDIBBits + lLineBytes * (lHeight - i - rectDst.top - 1) + rectDst.left; // 拷貝每一行,寬度為rectSrc.right - rectSrc.left memcpy(lpDst, lpSrc, rectSrc.right - rectSrc.left); } } // 復(fù)制平移后的圖像 memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); // 釋放內(nèi)存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); // 返回 return TRUE;}/************************************************************************* * * 函數(shù)名稱: * MirrorDIB() * * 參數(shù): * LPSTR lpDIBBits - 指向源DIB圖像指針 * LONG lWidth - 源圖像寬度(象素?cái)?shù)) * LONG lHeight - 源圖像高度(象素?cái)?shù)) * BOOL bDirection - 鏡像的方向,TRUE表示水平鏡像,F(xiàn)ALSE表示垂直鏡像 * * 返回值: * BOOL - 鏡像成功返回TRUE,否則返回FALSE。 * * 說明: * 該函數(shù)用來鏡像DIB圖像。可以指定鏡像的方式是水平還是垂直。 * ************************************************************************/BOOL WINAPI MirrorDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, BOOL bDirection){ // 指向源圖像的指針 LPSTR lpSrc; // 指向要復(fù)制區(qū)域的指針 LPSTR lpDst; // 指向復(fù)制圖像的指針 LPSTR lpBits; HLOCAL hBits; // 循環(huán)變量 LONG i; LONG j; // 圖像每行的字節(jié)數(shù) LONG lLineBytes; // 計(jì)算圖像每行的字節(jié)數(shù) lLineBytes = WIDTHBYTES(lWidth * 8); // 暫時(shí)分配內(nèi)存,以保存一行圖像 hBits = LocalAlloc(LHND, lLineBytes); if (hBits == NULL) { // 分配內(nèi)存失敗 return FALSE; } // 鎖定內(nèi)存 lpBits = (char * )LocalLock(hBits); // 判斷鏡像方式 if (bDirection) { // 水平鏡像 // 針對(duì)圖像每行進(jìn)行操作 for(i = 0; i < lHeight; i++) { // 針對(duì)每行圖像左半部分進(jìn)行操作 for(j = 0; j < lWidth / 2; j++) { // 指向倒數(shù)第i行,第j個(gè)象素的指針 lpSrc = (char *)lpDIBBits + lLineBytes * i + j; // 指向倒數(shù)第i行,倒數(shù)第j個(gè)象素的指針 lpDst = (char *)lpDIBBits + lLineBytes * (i + 1) - j; // 備份一個(gè)象素 *lpBits = *lpDst; // 將倒數(shù)第i行,第j個(gè)象素復(fù)制到倒數(shù)第i行,倒數(shù)第j個(gè)象素 *lpDst = *lpSrc; // 將倒數(shù)第i行,倒數(shù)第j個(gè)象素復(fù)制到倒數(shù)第i行,第j個(gè)象素 *lpSrc = *lpBits; } } } else { // 垂直鏡像 // 針對(duì)上半圖像進(jìn)行操作 for(i = 0; i < lHeight / 2; i++) { // 指向倒數(shù)第i行象素起點(diǎn)的指針 lpSrc = (char *)lpDIBBits + lLineBytes * i; // 指向第i行象素起點(diǎn)的指針 lpDst = (char *)lpDIBBits + lLineBytes * (lHeight - i - 1); memcpy(lpBits, lpDst, lLineBytes); // 將倒數(shù)第i行象素復(fù)制到第i行 memcpy(lpDst, lpSrc, lLineBytes); // 將第i行象素復(fù)制到倒數(shù)第i行 memcpy(lpSrc, lpBits, lLineBytes); } } // 釋放內(nèi)存 LocalUnlock(hBits);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -