19,468
社区成员
发帖
与我相关
我的任务
分享
/**
* 快速旋转指定的Dib对象
* @param pDib 待旋转的Dib对象
* @param nAngle 旋转角度(角度制)
*/
void DIB_RotateFast(CDib *pDib, int nAngle) {
int i, j;
CDib *pTmp;
nAngle %= 360;
BYTE **scanLines = new BYTE*[pDib->m_nHeight];
BYTE *pScanLine = pDib->m_pBits;
for (i = 0; i < pDib->m_nHeight; i++) {
*(scanLines+i) = pScanLine;
pScanLine += pDib->m_nPitch;
}
switch (nAngle) {
case 0:
delete scanLines;
return;
case 90:
pTmp = new CDib(pDib->m_nHeight, pDib->m_nWidth, COLOR_BLACK);
DIB_Filter(pTmp, dib_Rotate90Filter, scanLines);
*pDib = *pTmp;
delete scanLines;
delete pTmp;
return;
case 180:
DIB_Flip(pDib, FLIP_HORIZONTAL | FLIP_VERTICAL);
return;
case 270:
pTmp = new CDib(pDib->m_nHeight, pDib->m_nWidth, COLOR_BLACK);
DIB_Filter(pTmp, dib_Rotate270Filter, scanLines);
*pDib = *pTmp;
delete scanLines;
delete pTmp;
return;
default:
break;
}
double dAngle = nAngle/180.0 * PI;
int nSin = (int)(sin(dAngle)*65536.0+0.5);
int nCos = (int)(cos(dAngle)*65536.0+0.5);
POINT vertex[] = {
{0, 0},
{(pDib->m_nWidth*nCos) >> 16, (pDib->m_nWidth*nSin) >> 16},
{(pDib->m_nWidth*nCos + pDib->m_nHeight*nSin) >> 16, (pDib->m_nWidth*nSin - pDib->m_nHeight*nCos) >> 16},
{(pDib->m_nHeight*nSin) >> 16, (-pDib->m_nHeight*nCos) >> 16}
};
POINT newVertex[4];
if (nAngle > 0 && nAngle < 90) {
newVertex[0] = vertex[0];
newVertex[1] = vertex[1];
newVertex[2] = vertex[2];
newVertex[3] = vertex[3];
} else if (nAngle > 90 && nAngle < 180) {
newVertex[0] = vertex[1];
newVertex[1] = vertex[2];
newVertex[2] = vertex[3];
newVertex[3] = vertex[0];
} else if (nAngle > 180 && nAngle < 270) {
newVertex[0] = vertex[2];
newVertex[1] = vertex[3];
newVertex[2] = vertex[0];
newVertex[3] = vertex[1];
} else {
newVertex[0] = vertex[3];
newVertex[1] = vertex[0];
newVertex[2] = vertex[1];
newVertex[3] = vertex[2];
}
SIZE newSize;
int edgeSlope[4];
int edgeConst[4];
int deltaX = nCos*newVertex[0].x+nSin*newVertex[1].y;
int deltaY = nCos*newVertex[1].y-nSin*newVertex[0].x;
dib_GetEdgeFormulas(newVertex, &newSize, edgeSlope, edgeConst);
pTmp = new CDib(newSize.cx, newSize.cy, g_colorKey);
int ox, oy;
int boundLeft, boundRight;
BYTE *pVInc = pTmp->m_pBits; // 初始化为第一个扫描行的首地址(也就是整个图像数据的首址)
// 水平方向的增量指针。每操作完一个像素,它就被指向下一个像素
BYTE *pHInc = NULL; // 它将在每次对一个扫描行开始处理之前被赋值
int actualY = -pTmp->m_nHeight;
for (i = 0; i > actualY; i--) {
if (i > newVertex[0].y) {
boundLeft = (edgeSlope[0]*i + edgeConst[0]) >> 16;
} else {
boundLeft = (edgeSlope[1]*i + edgeConst[1]) >> 16;
}
if (i > newVertex[2].y) {
boundRight = (edgeSlope[2]*i + edgeConst[2]) >> 16;
} else {
boundRight = (edgeSlope[3]*i + edgeConst[3]) >> 16;
}
pHInc = pVInc+boundLeft+boundLeft+boundLeft; // 把水平增量指针初始化为当前扫描行的首址
for (j = boundLeft; j < boundRight; j++) {
ox = (nCos*j+nSin*i+deltaX) >> 16;
oy = -((nCos*i-nSin*j+deltaY) >> 16);
ox = ox < 0 ? 0 : ox;
ox = ox >= pDib->m_nWidth ? pDib->m_nWidth-1 : ox;
oy = oy < 0 ? 0 : oy;
oy = oy >= pDib->m_nHeight ? pDib->m_nHeight-1 : oy;
dib_SetColor(pHInc, dib_GetColor(*(scanLines+oy)+ox+ox+ox));
pHInc += PIXELSIZE; // 一个像素数据过滤完成,指针指向下一个
}
pVInc += pTmp->m_nPitch; // 一个扫描行处理完,指针指向下一行
}
*pDib = *pTmp;
delete scanLines;
delete pTmp;
}