너비와 높이 값을 바꾸는 것 이상의 것이 있습니다! 사각형을 가져 와서 45도 회전하면 너비와 높이를 바꿀 필요가 없습니다. 이미지는 실제로는 이전과 같은 넓이와 높이로 sqrt (2) 배가됩니다 (대각선 모서리에서 다른 구석으로의 길이는 sqrt입니다. (1^2 + 1^2)에 인접한 모서리 사이의 길이를 곱한 것입니다. 요점은 간단한 스왑보다 조금 더 나은 새로운 이미지 크기를 계산해야한다는 것입니다.
이미지 회전 루틴을 찾을 수 없습니다. 10 년 또는 15 년 전과 마찬가지로 손쉽게 가까운 곳에서 그물을 볼 수 있습니다. 이제 우리가 가지고있는 모든 빠른 그래픽 하드웨어가 많은 사람들의 필요를 충족시켜줍니다.
90 °, 180 ° 또는 270 ° - 나는 확실히 할 수는 없지만 폭과 높이의 단순한 교환으로 의심해 봅니다. 여기 기사 : http://www.codeproject.com/Articles/21446/Fast-Image-Rotation-For-NET-Compact-Framework
그러나 임의의 각도로 회전하려면 다음을 읽으십시오.
나는 그것이 C이고 자바 스크립트를 사용하고 있다는 것을 알았지 만, 회전 수학은 단지 동일하고, 필요에 따라 equiv javascript 함수를 무시/사용합니다.
// RotateMemoryDC rotates a memory DC and returns the rotated DC as well as its dimensions
HBITMAP RotateMemoryDC(HBITMAP hBmpSrc, float angleDeg)
{
HBITMAP hBmpDst;
float x1, x2, x3, x4, y1, y2, y3, y4, cA, sA;
float CtX, CtY, orgX, orgY, divisor;
int OfX, OfY;
int stepX, stepY;
int iorgX, iorgY;
RECT rt;
pBGR src, dst, dstLine;
BITMAPINFO bi;
// my edits
BITMAP bm;
int SrcX, SrcY, dstX, dstY; // were input variables, with the & symbol in front of them (input/output vars)\
HDC hdcSrc, hdcDst, hdcScreen;
HBITMAP oldDstBmp, oldSrcBmp;
GetObject(hBmpSrc, sizeof(bm), &bm);
SrcX = bm.bmWidth;
SrcY = bm.bmHeight;
// Rotate the bitmap around the center
CtX = ((float) SrcX)/2;
CtY = ((float) SrcY)/2;
// First, calculate the destination positions for the four courners to get dstX and dstY
float angleRad = angleDeg * 3.1415926/180.0;
cA = (float) cos(angleRad);
sA = (float) sin(angleRad);
x1 = CtX + (-CtX) * cA - (-CtY) * sA;
x2 = CtX + (SrcX - CtX) * cA - (-CtY) * sA;
x3 = CtX + (SrcX - CtX) * cA - (SrcY - CtY) * sA;
x4 = CtX + (-CtX) * cA - (SrcY - CtY) * sA;
y1 = CtY + (-CtY) * cA + (-CtX) * sA;
y2 = CtY + (SrcY - CtY) * cA + (-CtX) * sA;
y3 = CtY + (SrcY - CtY) * cA + (SrcX - CtX) * sA;
y4 = CtY + (-CtY) * cA + (SrcX - CtX) * sA;
OfX = ((int) floor(min4(x1, x2, x3, x4)));
OfY = ((int) floor(min4(y1, y2, y3, y4)));
dstX = ((int) ceil(max4(x1, x2, x3, x4))) - OfX;
dstY = ((int) ceil(max4(y1, y2, y3, y4))) - OfY;
// Create the new memory DC
hdcScreen = GetDC(NULL);
hdcDst = CreateCompatibleDC(hdcScreen);
hdcSrc = CreateCompatibleDC(hdcScreen);
hBmpDst = CreateCompatibleBitmap(hdcScreen, dstX, dstY);
oldDstBmp = (HBITMAP)SelectObject(hdcDst, hBmpDst);
oldSrcBmp = (HBITMAP)SelectObject(hdcSrc, hBmpSrc);
// Fill the new memory DC with the current Window color
rt.left = 0;
rt.top = 0;
rt.right = dstX;
rt.bottom = dstY;
HBRUSH redBrush = CreateSolidBrush(RGB(255,0,0));
FillRect(hdcDst, &rt, redBrush);
DeleteObject(redBrush);
// Get the bitmap bits for the source and destination
src = MyGetDibBits(hdcSrc, hBmpSrc, SrcX, SrcY);
dst = MyGetDibBits(hdcDst, hBmpDst, dstX, dstY);
dstLine = dst;
divisor = cA*cA + sA*sA;
// Step through the destination bitmap
for (stepY = 0; stepY < dstY; stepY++)
{
for (stepX = 0; stepX < dstX; stepX++)
{
// Calculate the source coordinate
orgX = (cA * (((float) stepX + OfX) + CtX * (cA - 1)) + sA * (((float) stepY + OfY) + CtY * (sA - 1)))/divisor;
orgY = CtY + (CtX - ((float) stepX + OfX)) * sA + cA *(((float) stepY + OfY) - CtY + (CtY - CtX) * sA);
iorgX = (int) orgX;
iorgY = (int) orgY;
if ((iorgX >= 0) && (iorgY >= 0) && (iorgX < SrcX) && (iorgY < SrcY))
{
// Inside the source bitmap -> copy the bits
dstLine[dstX - stepX - 1] = src[iorgX + iorgY * SrcX];
}
else
{
// Outside the source -> set the color to light grey
// dstLine[dstX - stepX - 1].b = 240;
// dstLine[dstX - stepX - 1].g = 20;
// dstLine[dstX - stepX - 1].r = 240;
}
}
dstLine = dstLine + dstX;
}
// Set the new Bitmap
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth = dstX;
bi.bmiHeader.biHeight = dstY;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = dstX * 4 * dstY;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
SetDIBits(hdcDst, hBmpDst, 0, dstY, dst, &bi, DIB_RGB_COLORS);
// Free the color arrays
free(src);
free(dst);
SelectObject(hdcSrc, oldSrcBmp);
SelectObject(hdcDst, oldDstBmp);
ReleaseDC(NULL, hdcScreen);
DeleteDC(hdcSrc);
DeleteDC(hdcDst);
return hBmpDst;
}
jsFiddle이 있습니까? – alex
회전 알고리즘의 구현을 보여줄 수 있습니까? – Philipp
나는 질문을 업데이트했다, 나는 그것이 더 분명해야한다고 생각한다 : D – kaljak