1

わかりました、これをもっと明確にする必要があると思います:)

私のコードは正方形の画像では機能していますが、長方形の画像では何もしていません。imageData.width と imageData.height がまだ同じで、変更できないためだと思います。

どうすればそれを機能させることができるか知っていますか?

var canvas = document.getElementById("canvas0calc");
var ctx  = canvas.getContext('2d');

var objImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

// swap canvas size
var temp = canvas.width;
canvas.width = canvas.height;
canvas.height = temp;


//create new Array for Data
var newImageData = new Array(objImageData.height);
for (var k = 0; k < newImageData.length; k++) {
    newImageData[k] = new Array(objImageData.width);
}

//the actual matrix-rotate algorithm which is working perfectly
for (var i = 0; i < objImageData.height; i++) {
    for (var j = 0; j < objImageData.width; j++) {
        newImageData[i][j] = [objImageData.data[((i*(objImageData.width*4)) + ((objImageData.width - j - 1)*4))], objImageData.data[((i*(objImageData.width*4)) + ((objImageData.width - j - 1)*4)) + 1],objImageData.data[((i*(objImageData.width*4)) + ((objImageData.width - j - 1)*4)) + 2],objImageData.data[((i*(objImageData.width*4)) + ((objImageData.width - j - 1)*4)) + 3]];
    }
}

var resultArray = new Array(objImageData.width * objImageData.height * 4);
var count = 0;
for (var y = 0; y < newImageData.length; y++) {
    for (var x = 0; x < newImageData[0].length; x++) {
        for (var z = 0; z < 4; z++) {
            resultArray[count++] = newImageData[x][y][z];
        }
    }
}

for (var u = 0; u < objImageData.data.length; u++) {
    objImageData.data[u] = resultArray[u];
}

ctx.putImageData(objImageData, 0, 0);
4

1 に答える 1

3

幅と高さの値を交換するだけではありません。正方形を取り、それを 45° 回転させた場合、幅と高さを交換しても何も起こりません - 画像は実際には以前の sqrt(2) 倍の幅と高さです (1 つの対角線の角から別の角までの長さは sqrt です)。 ( 1^2 + 1^2) は、隣接するコーナー間の長さの倍数ポイントは、新しい画像のサイズを単純なスワップよりも少し正確に計算する必要があるということです。

10 年か 15 年前のように簡単に画像回転ルーチンをネット上で見つけることはできないようです。多くの人々のニーズに対応できるようになっているのは、現在私たちが持っているすべての高速グラフィックス ハードウェアです。

90°、180°、または 270° のいずれで回転させたいかは不明です。確かではありませんが、幅と高さを単純に交換することでそうなるのではないかと思います。その場合は、こちらの記事を参照してください: http://www.codeproject.com/Articles/21446/Fast-Image-Rotation-For-NET-Compact-Framework

ただし、任意の角度で回転させたい場合は、読み進めてください。

私はそれがCであり、あなたがjavascriptを使用していることに気づきました-しかし、いずれにせよ、回転計算はまったく同じです.必要に応じて同等の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;
}
于 2012-10-12T14:23:28.367 に答える