帮我用c++和mfc写图像旋转的函数RotateDIB(lpSrcDib, iRotateAngle)
时间: 2024-03-03 11:49:50 浏览: 77
好的,我会帮您实现这个图像旋转函数。下面是具体的代码实现:
```c++
void RotateDIB(BITMAPINFO* lpSrcDib, int iRotateAngle)
{
if (nullptr == lpSrcDib || iRotateAngle == 0) {
return;
}
// 获取源图像信息
LPSTR lpSrcStartBits = (LPSTR)lpSrcDib + lpSrcDib->bmiHeader.biSize + GetColorTableSize(lpSrcDib);
LONG lSrcWidth = lpSrcDib->bmiHeader.biWidth;
LONG lSrcHeight = abs(lpSrcDib->bmiHeader.biHeight);
// 计算旋转后的图像宽度和高度
double dRotate = (double)iRotateAngle * PI / 180;
double dSin = fabs(sin(dRotate));
double dCos = fabs(cos(dRotate));
LONG lNewWidth = (LONG)(lSrcWidth * dCos + lSrcHeight * dSin);
LONG lNewHeight = (LONG)(lSrcWidth * dSin + lSrcHeight * dCos);
// 申请新图像内存
HGLOBAL hNewDib = GlobalAlloc(GMEM_MOVEABLE, sizeof(BITMAPINFOHEADER) + GetColorTableSize(lpSrcDib) + lNewWidth * lNewHeight * 4);
if (nullptr == hNewDib) {
return;
}
BITMAPINFO* lpNewDib = (BITMAPINFO*)GlobalLock(hNewDib);
memcpy(lpNewDib, lpSrcDib, sizeof(BITMAPINFOHEADER) + GetColorTableSize(lpSrcDib));
lpNewDib->bmiHeader.biWidth = lNewWidth;
lpNewDib->bmiHeader.biHeight = lpSrcDib->bmiHeader.biHeight > 0 ? lNewHeight : -lNewHeight;
LPSTR lpNewStartBits = (LPSTR)lpNewDib + lpNewDib->bmiHeader.biSize + GetColorTableSize(lpNewDib);
memset(lpNewStartBits, 0, lNewWidth * lNewHeight * 4);
// 计算旋转中心点
LONG lSrcMidX = lSrcWidth / 2;
LONG lSrcMidY = lSrcHeight / 2;
LONG lNewMidX = lNewWidth / 2;
LONG lNewMidY = lNewHeight / 2;
// 逐像素旋转
for (LONG y = 0; y < lSrcHeight; y++) {
for (LONG x = 0; x < lSrcWidth; x++) {
// 计算旋转后的像素坐标
LONG lNewX = (LONG)((x - lSrcMidX) * dCos + (y - lSrcMidY) * dSin + lNewMidX);
LONG lNewY = (LONG)((x - lSrcMidX) * dSin + (y - lSrcMidY) * dCos + lNewMidY);
// 判断新坐标是否在图像范围内
if (lNewX >= 0 && lNewX < lNewWidth && lNewY >= 0 && lNewY < lNewHeight) {
// 获取旧像素值
LONG lSrcPos = (y * lSrcWidth + x) * 4;
BYTE bRed = lpSrcStartBits[lSrcPos + 2];
BYTE bGreen = lpSrcStartBits[lSrcPos + 1];
BYTE bBlue = lpSrcStartBits[lSrcPos];
BYTE bAlpha = lpSrcStartBits[lSrcPos + 3];
// 设置新像素值
LONG lNewPos = (lNewY * lNewWidth + lNewX) * 4;
lpNewStartBits[lNewPos + 2] = bRed;
lpNewStartBits[lNewPos + 1] = bGreen;
lpNewStartBits[lNewPos] = bBlue;
lpNewStartBits[lNewPos + 3] = bAlpha;
}
}
}
// 更新图像信息
lpSrcDib->bmiHeader.biWidth = lNewWidth;
lpSrcDib->bmiHeader.biHeight = lpNewDib->bmiHeader.biHeight;
memcpy(lpSrcStartBits, lpNewStartBits, lNewWidth * lNewHeight * 4);
// 释放内存
GlobalUnlock(hNewDib);
GlobalFree(hNewDib);
}
```
这个函数中,我们首先获取源图像信息,然后计算旋转后的图像宽度和高度,申请新的内存空间,并对图像进行旋转。最后,我们更新源图像信息,并将新的像素数据拷贝到旧的内存空间中,最后释放内存。
阅读全文