📄 geotrans.cpp
字号:
LocalFree(hBits); // 返回 return TRUE;}/************************************************************************* * * 函数名称: * TransposeDIB() * * 参数: * LPSTR lpDIB - 指向源DIB的指针 * * 返回值: * BOOL - 转置成功返回TRUE,否则返回FALSE。 * * 说明: * 该函数用来转置DIB图像,即图像x、y坐标互换。函数将不会改变图像的大小, * 但是图像的高宽将互换。 * ************************************************************************/BOOL WINAPI TransposeDIB(LPSTR lpDIB){ // 图像的宽度和高度 LONG lWidth; LONG lHeight; // 指向源图像的指针 LPSTR lpDIBBits; // 指向源象素的指针 LPSTR lpSrc; // 指向转置图像对应象素的指针 LPSTR lpDst; // 指向转置图像的指针 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; // 指向BITMAPINFO结构的指针(Win3.0) LPBITMAPINFOHEADER lpbmi; // 指向BITMAPCOREINFO结构的指针 LPBITMAPCOREHEADER lpbmc; // 循环变量 LONG i; LONG j; // 图像每行的字节数 LONG lLineBytes; // 新图像每行的字节数 LONG lNewLineBytes; // 获取指针 lpbmi = (LPBITMAPINFOHEADER)lpDIB; lpbmc = (LPBITMAPCOREHEADER)lpDIB; // 找到源DIB图像象素起始位置 lpDIBBits = ::FindDIBBits(lpDIB); // 获取图像的"宽度"(4的倍数) lWidth = ::DIBWidth(lpDIB); // 获取图像的高度 lHeight = ::DIBHeight(lpDIB); // 计算图像每行的字节数 lLineBytes = WIDTHBYTES(lWidth * 8); // 计算新图像每行的字节数 lNewLineBytes = WIDTHBYTES(lHeight * 8); // 暂时分配内存,以保存新图像 hNewDIBBits = LocalAlloc(LHND, lWidth * lNewLineBytes); // 判断是否内存分配失败 if (hNewDIBBits == NULL) { // 分配内存失败 return FALSE; } // 锁定内存 lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 针对图像每行进行操作 for(i = 0; i < lHeight; i++) { // 针对每行图像每列进行操作 for(j = 0; j < lWidth; j++) { // 指向源DIB第i行,第j个象素的指针 lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j; // 指向转置DIB第j行,第i个象素的指针 // 注意此处lWidth和lHeight是源DIB的宽度和高度,应该互换 lpDst = (char *)lpNewDIBBits + lNewLineBytes * (lWidth - 1 - j) + i; // 复制象素 *lpDst = *lpSrc; } } // 复制转置后的图像 memcpy(lpDIBBits, lpNewDIBBits, lWidth * lNewLineBytes); // 互换DIB中图像的高宽 if (IS_WIN30_DIB(lpDIB)) { // 对于Windows 3.0 DIB lpbmi->biWidth = lHeight; lpbmi->biHeight = lWidth; } else { // 对于其它格式的DIB lpbmc->bcWidth = (unsigned short) lHeight; lpbmc->bcHeight = (unsigned short) lWidth; } // 释放内存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); // 返回 return TRUE;}/************************************************************************* * * 函数名称: * ZoomDIB() * * 参数: * LPSTR lpDIB - 指向源DIB的指针 * float fXZoomRatio - X轴方向缩放比率 * float fYZoomRatio - Y轴方向缩放比率 * * 返回值: * HGLOBAL - 缩放成功返回新DIB句柄,否则返回NULL。 * * 说明: * 该函数用来缩放DIB图像,返回新生成DIB的句柄。 * ************************************************************************/HGLOBAL WINAPI ZoomDIB(LPSTR lpDIB, float fXZoomRatio, float fYZoomRatio){ // 源图像的宽度和高度 LONG lWidth; LONG lHeight; // 缩放后图像的宽度和高度 LONG lNewWidth; LONG lNewHeight; // 缩放后图像的宽度(lNewWidth',必须是4的倍数) LONG lNewLineBytes; // 指向源图像的指针 LPSTR lpDIBBits; // 指向源象素的指针 LPSTR lpSrc; // 缩放后新DIB句柄 HDIB hDIB; // 指向缩放图像对应象素的指针 LPSTR lpDst; // 指向缩放图像的指针 LPSTR lpNewDIB; LPSTR lpNewDIBBits; // 指向BITMAPINFO结构的指针(Win3.0) LPBITMAPINFOHEADER lpbmi; // 指向BITMAPCOREINFO结构的指针 LPBITMAPCOREHEADER lpbmc; // 循环变量(象素在新DIB中的坐标) LONG i; LONG j; // 象素在源DIB中的坐标 LONG i0; LONG j0; // 图像每行的字节数 LONG lLineBytes; // 找到源DIB图像象素起始位置 lpDIBBits = ::FindDIBBits(lpDIB); // 获取图像的宽度 lWidth = ::DIBWidth(lpDIB); // 计算图像每行的字节数 lLineBytes = WIDTHBYTES(lWidth * 8); // 获取图像的高度 lHeight = ::DIBHeight(lpDIB); // 计算缩放后的图像实际宽度 // 此处直接加0.5是由于强制类型转换时不四舍五入,而是直接截去小数部分 lNewWidth = (LONG) (::DIBWidth(lpDIB) * fXZoomRatio + 0.5); // 计算新图像每行的字节数 lNewLineBytes = WIDTHBYTES(lNewWidth * 8); // 计算缩放后的图像高度 lNewHeight = (LONG) (lHeight * fYZoomRatio + 0.5); // 分配内存,以保存新DIB hDIB = (HDIB) ::GlobalAlloc(GHND, lNewLineBytes * lNewHeight + *(LPDWORD)lpDIB + ::PaletteSize(lpDIB)); // 判断是否内存分配失败 if (hDIB == NULL) { // 分配内存失败 return NULL; } // 锁定内存 lpNewDIB = (char * )::GlobalLock((HGLOBAL) hDIB); // 复制DIB信息头和调色板 memcpy(lpNewDIB, lpDIB, *(LPDWORD)lpDIB + ::PaletteSize(lpDIB)); // 找到新DIB象素起始位置 lpNewDIBBits = ::FindDIBBits(lpNewDIB); // 获取指针 lpbmi = (LPBITMAPINFOHEADER)lpNewDIB; lpbmc = (LPBITMAPCOREHEADER)lpNewDIB; // 更新DIB中图像的高度和宽度 if (IS_WIN30_DIB(lpNewDIB)) { // 对于Windows 3.0 DIB lpbmi->biWidth = lNewWidth; lpbmi->biHeight = lNewHeight; } else { // 对于其它格式的DIB lpbmc->bcWidth = (unsigned short) lNewWidth; lpbmc->bcHeight = (unsigned short) lNewHeight; } // 针对图像每行进行操作 for(i = 0; i < lNewHeight; i++) { // 针对图像每列进行操作 for(j = 0; j < lNewWidth; j++) { // 指向新DIB第i行,第j个象素的指针 // 注意此处宽度和高度是新DIB的宽度和高度 lpDst = (char *)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + j; // 计算该象素在源DIB中的坐标 i0 = (LONG) (i / fYZoomRatio + 0.5); j0 = (LONG) (j / fXZoomRatio + 0.5); // 判断是否在源图范围内 if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)) { // 指向源DIB第i0行,第j0个象素的指针 lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0; // 复制象素 *lpDst = *lpSrc; } else { // 对于源图中没有的象素,直接赋值为255 * ((unsigned char*)lpDst) = 255; } } } // 返回 return hDIB;}/************************************************************************* * * 函数名称: * RotateDIB() * * 参数: * LPSTR lpDIB - 指向源DIB的指针 * int iRotateAngle - 旋转的角度(0-360度) * * 返回值: * HGLOBAL - 旋转成功返回新DIB句柄,否则返回NULL。 * * 说明: * 该函数用来以图像中心为中心旋转DIB图像,返回新生成DIB的句柄。 * 调用该函数会自动扩大图像以显示所有的象素。函数中采用最邻近插 * 值算法进行插值。 * ************************************************************************/HGLOBAL WINAPI RotateDIB(LPSTR lpDIB, int iRotateAngle){ // 源图像的宽度和高度 LONG lWidth; LONG lHeight; // 旋转后图像的宽度和高度 LONG lNewWidth; LONG lNewHeight; // 图像每行的字节数 LONG lLineBytes; // 旋转后图像的宽度(lNewWidth',必须是4的倍数) LONG lNewLineBytes; // 指向源图像的指针 LPSTR lpDIBBits; // 指向源象素的指针 LPSTR lpSrc; // 旋转后新DIB句柄 HDIB hDIB; // 指向旋转图像对应象素的指针 LPSTR lpDst; // 指向旋转图像的指针 LPSTR lpNewDIB; LPSTR lpNewDIBBits; // 指向BITMAPINFO结构的指针(Win3.0) LPBITMAPINFOHEADER lpbmi; // 指向BITMAPCOREINFO结构的指针 LPBITMAPCOREHEADER lpbmc; // 循环变量(象素在新DIB中的坐标) LONG i; LONG j; // 象素在源DIB中的坐标 LONG i0; LONG j0; // 旋转角度(弧度) float fRotateAngle; // 旋转角度的正弦和余弦 float fSina, fCosa; // 源图四个角的坐标(以图像中心为坐标系原点) float fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4; // 旋转后四个角的坐标(以图像中心为坐标系原点) float fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4; // 两个中间常量 float f1,f2; // 找到源DIB图像象素起始位置 lpDIBBits = ::FindDIBBits(lpDIB); // 获取图像的"宽度"(4的倍数) lWidth = ::DIBWidth(lpDIB); // 计算图像每行的字节数 lLineBytes = WIDTHBYTES(lWidth * 8); // 获取图像的高度 lHeight = ::DIBHeight(lpDIB); // 将旋转角度从度转换到弧度 fRotateAngle = (float) RADIAN(iRotateAngle); // 计算旋转角度的正弦 fSina = (float) sin((double)fRotateAngle); // 计算旋转角度的余弦 fCosa = (float) cos((double)fRotateAngle); // 计算原图的四个角的坐标(以图像中心为坐标系原点) fSrcX1 = (float) (- (lWidth - 1) / 2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -