gpt4 book ai didi

javascript - 将图像绘制到 Canvas 会为绘制的每个新图像返回 InvalidStateError,然后成功

转载 作者:太空狗 更新时间:2023-10-29 13:15:57 38 4
gpt4 key购买 nike

情况

我有一个类似网格的无序列表,其中包含 144 (90px x 90px) 个图像 (12x12),可以旋转。我的最终目标是获取 144 个图像网格并将其保存为 1 个图像。

当前解决方案

我当前的解决方案让我遵循以下步骤:

  1. 创建一张图像宽度 x 12 宽和图像高度 x 12 高的 Canvas 。这是代表最终产品图像。
  2. 遍历列表项(图像),从项目中提取图像 src 并将其绘制到与图像大小相同的自己的 Canvas 上。
  3. 旋转新的小 Canvas ,但它的图像已在网格上旋转。
  4. 将新的小 Canvas 绘制到当前指针的 x 和 y 处的最终结果 Canvas 上。

注意事项

当我循环浏览图像时,我会跟踪一个指针(我当前在 Canvas 上的位置)。我通过维护一行和一个列号来做到这一点。它们代表我正在绘制的图像的当前行和列。我使用它们,乘以单个图像的宽度和高度,以获得 Canvas 上精确的 x 和 y 坐标来绘制下一个图像。

当前问题

当我调用函数来创建、绘制和生成 Canvas 的 base64 时,我收到以下错误消息:“InvalidStateError:尝试使用一个不可用或不再可用的对象。” .如果此错误在 100% 的时间内发生,我会假设这是因为我正在绘制到 Canvas 上的图像尚未加载或根本未加载,但是,我只收到一次此错误我加载的每个新图像。例如,如果我有一个 144 图像网格,即 2 个不同的图像,每个图像绘制 72 次,我将收到两次 InvalidStateError,然后第三次调用该函数,它将成功。

当前代码

请记住,这只是用于测试保存图像的尖峰代码,我知道需要进行一些重构。

generateThumbnail: function(){
var builder = this,
canvas = document.createElement('canvas'),
content,
row = 0,
col = 0;

// width is single image width (90) x number of tiles wide (usually 12)
canvas.width = 90 * builder.grid[0];
// height is single image height (90) x number of tiles high (usually 12)
canvas.height = 90 * builder.grid[1];
// get 2d context of new canvas
context = canvas.getContext("2d");

// loop through all of the images on the grid
$.each($(".pattern-grid li"), function(i, tile) {
var $tile = $(tile),
image = new Image(),
src = $tile.find("img").attr("src"),
width,
height,
buffer,
bufferctx,
x,
y;

// set crossOrigin of image to anonymous as these images are loaded via CORS
image.crossOrigin = "Anonymous";

// increase row number by 1 if it has reached the end of the row and its not the first image being drawn
if(i % builder.grid[0] == 0 && i != 0){
row++;
}
// Set Column to 0 if it is a new row, otherwise increase column by 1 (unless it is the first image being drawn)
if(col == builder.grid[0]-1){
col = 0;
}else if(i != 0){
col++;
}

// determine if there was no image drawn at this location
if(src != undefined){
image.src = src;
// get the width and height the image, to be used for the small canvas and where to draw it
width = image.width;
height = image.height;
// create a new buffer canvas to draw the image to, this will be used to apply any rotations that may exist
buffer = document.createElement("canvas");
//set width and height of the buffer to the current images width and height
buffer.width = width;
buffer.height = height;
bufferctx = buffer.getContext("2d");
//Determine x and y coordinates to draw the small canvas using row and column numbers
x = col*width;
y = row*height;
//Save current state of buffer canvas
bufferctx.save();
//translate and then rotate the buffer canvas by the image's rotation
bufferctx.translate(width/2, height/2);
bufferctx.rotate($tile.find("img").data("rotation")*Math.PI/180);
bufferctx.translate(width/2*-1, height/2*-1);
//draw image to buffer canvas and restore its context
bufferctx.drawImage(image, 0, 0);
bufferctx.restore();
//draw the buffer canvas to the main canvas at predetermined x and y
context.drawImage(buffer, x, y, width, height);
}
});
return canvas.toDataURL();
}

最佳答案

我能够将@abiessu 的建议与 onload 结合使用,并与闭包配对以保存函数的状态。我的有效解决方案是:

generateThumbnail: function(){
var builder = this,
canvas = document.createElement('canvas'),
content,
row = 0,
col = 0;
// width is single image width (90) x number of tiles wide (usually 12)
canvas.width = 90 * builder.grid[0];
// height is single image height (90) x number of tiles high (usually 12)
canvas.height = 90 * builder.grid[1];
context = canvas.getContext("2d");
// loop through all of the images on the grid
$.each($(".pattern-grid li"), function(i, tile) {
var $tile = $(tile),
image = new Image(),
src = $tile.find("img").attr("src");
// set crossOrigin of image to anonymous as these images are loaded via CORS
image.crossOrigin = "Anonymous";
// increase row number by 1 if it has reached the end of the row and its not the first image being drawn
if(i % builder.grid[0] == 0 && i != 0){
row++;
}
// increase row number by 1 if it has reached the end of the row and its not the first image being drawn
if(col == builder.grid[0]-1){
col = 0;
}else if(i != 0){
col++;
}
image.onload = function(row, col){
return function(){
// determine if there was no image drawn at this location
if(src != undefined){
var width = image.width,
height = image.height,
buffer = document.createElement("canvas"),
bufferctx,
x,
y;
buffer.width = width;
buffer.height = height;
bufferctx = buffer.getContext("2d");
x = col*width;
y = row*height;
bufferctx.save();
bufferctx.translate(width/2, height/2);
bufferctx.rotate($tile.find("img").data("rotation")*Math.PI/180);
bufferctx.translate(width/2*-1, height/2*-1);
bufferctx.drawImage(image, 0, 0);
bufferctx.restore();
context.drawImage(buffer, x, y, width, height);
}
}
}(row, col);
image.src = $tile.find("img").attr("src");
});
window.canvas = canvas;
}

关于javascript - 将图像绘制到 Canvas 会为绘制的每个新图像返回 InvalidStateError,然后成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19637270/

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