gpt4 book ai didi

javascript - 在 Canvas 中旋转图像数据

转载 作者:行者123 更新时间:2023-11-30 13:13:55 26 4
gpt4 key购买 nike

好吧,我想我必须说得更清楚:)

我的代码适用于方形图像,但它对矩形图像无效。我认为这是因为 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);

最佳答案

它不仅仅是交换宽度和高度值!如果我拿一个正方形然后将其旋转 45°,然后交换宽度和高度将无济于事 - 图像实际上是以前的宽度和高度的 sqrt(2) 倍(从一个对 Angular Angular 到另一个 Angular 的长度是 sqrt ( 1^2 + 1^2) 乘以相邻 Angular 之间的长度。关键是,您需要比简单交换更好地计算新图像尺寸。

我似乎无法像 10 或 15 年前那样轻松地在网上找到图像旋转例程 - 这是我们现在拥有的所有快速图形硬件,这使得它可以满足很多人的需求。

不清楚您是想旋转 90°、180° 还是 270° - 我怀疑是通过简单的宽度和高度交换来实现的,尽管我不能确定。如果是这样,请在此处查看这篇文章:http://www.codeproject.com/Articles/21446/Fast-Image-Rotation-For-NET-Compact-Framework

但是,如果您想旋转任意 Angular ,请继续阅读。

我意识到它是 C 并且您正在使用 javascript - 但无论如何,旋转数学是一样的,只需根据需要忽略/使用 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;
}

关于javascript - 在 Canvas 中旋转图像数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12857351/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com