void RotateImage(const BITMAPINFOHEADER* pDibSrc, const BITMAPINFOHEADER* pDibDst, double fAngle, double fScale) { CDib DibSrc = pDibSrc; CDib DibDst = pDibDst; int dxSrc = DibSrc.Width(); int dySrc = DibSrc.Height(); int dxDst = DibDst.Width(); int dyDst = DibDst.Height(); int lxSrc = dxSrc - 1; // Last X int lySrc = dySrc - 1; // Last Y double fAngleRadian = fAngle * PIdiv180; double duCol = sin(fAngleRadian) * (1.0 / fScale); double dvCol = cos(fAngleRadian) * (1.0 / fScale); double duRow = dvCol; double dvRow = -duCol; double fcxSrc = dxSrc / 2; double fcySrc = dySrc / 2; double fcxDst = dxDst / 2; double fcyDst = dyDst / 2; double uRow = fcxSrc - (fcxDst * dvCol + fcyDst * duCol); double vRow = fcySrc - (fcxDst * dvRow + fcyDst * duRow); int iDepth = DibDst.Depth(); for (int y = 0; y < dyDst; y++) { double u = uRow; double v = vRow; BYTE* pDst = DibDst.PtrXYExact(0, y); for (int x = 0; x < dxDst ; x++) { int sx = dtoi(u); int sy = dtoi(v); bool bInside = (sx >= 0 && sx <= lxSrc && sy >= 0 && sy <= lySrc); if (!bInside) { // Allow a 2 pixel edge to avoid seeing any mismatch with the clip rectangle bool bInsideEdge = (sx >= -2 && sx <= lxSrc+3 && sy >= -2 && sy <= lySrc+3); if (bInsideEdge) { if (sx >= -2 && sx < 0) sx = 0; if (sx <= lxSrc+3 && sx > lxSrc) sx = lxSrc; if (sy >= -2 && sy < 0) sy = 0; if (sy <= lySrc+3 && sy > lySrc) sy = lySrc; bInside = (sx >= 0 && sx <= lxSrc && sy >= 0 && sy <= lySrc); } } if (bInside) { BYTE* pSrc = DibSrc.PtrXYExact(sx, sy); *pDst++ = *pSrc++; if (iDepth == 3) { *pDst++ = *pSrc++; *pDst++ = *pSrc++; } } else { *pDst++ = 255; if (iDepth == 3) { *pDst++ = 255; *pDst++ = 255; } } u += duRow; v += dvRow; } uRow += duCol; vRow += dvCol; } }