Ошибка при вскрытии: INDEX_SIZE_ERR

Я рисую на холсте со следующей строкой:

ctx.drawImage(compositeImage, 0, 0, image.width, image.height, i, j, scaledCompositeImageWidth, scaledCompositeImageHeight);

Этот код выполнил ошибку в Safari, Chrome, Firefox (и даже IE, используя библиотеку google excanvas). Однако недавнее обновление Chrome теперь вызывает следующую ошибку:

Не удалось получить ошибку: INDEX_SIZE_ERR: исключение DOM 1

Этот код часто позиционирует часть или все нарисованное изображение на холсте, кто-нибудь понял, что здесь происходит?

Ответ 1

Является ли compositeImage ссылкой на действительное (полностью загруженное) изображение?

Я видел это исключение, если вы попытаетесь нарисовать изображение до его загрузки.

например.

img = new Image();
img.src = '/some/image.png';
ctx.drawImage( img, ..... ); // Throws error

Должно быть что-то вроде

img = new Image();
img.onload = function() {
  ctx.drawImage( img, .... );
};
img.src = '/some/image.png';

Чтобы изображение загрузилось.

Ответ 2

Почему?

Это происходит, если вы рисуете изображение перед его загрузкой, потому что это то, что указывает черновик html5 2dcontext для интерпретации первого аргумента drawImage():

Если один из аргументов sw или sh равен нулю, реализация должна вызвать исключение INDEX_SIZE_ERR.

sw, sh - ширина и высота исходного изображения

@jimr ответ хороший, просто подумал, что было бы интересно добавить это здесь.

Ответ 3

Другая причина этой ошибки - размеры исходного изображения слишком велики; они выходят за рамки фактических размеров изображения. Когда это произойдет, вы увидите эту ошибку в IE, но не в Chrome или Firefox.

Скажем, у вас есть изображение 150x150:

var imageElement = ...;

Затем, если вы попытаетесь нарисовать его, используя большие размеры источника:

var sourceX = 0;
var sourceY = 0;
var sourceWidth = 200; // Too big!
var sourceHeight = 200; // Too big!
canvasContext.drawImage(imageElement, 
   sourceX, sourceY, sourceWidth, sourceHeight, // Too big! Will throw INDEX_SIZE_ERR
   destX, destY, destWidth, destHeight);

Это запустит INDEX_SIZE_ERR в IE. (Последний IE является IE11 на момент написания этой статьи.)

Исправление просто ограничивает размеры источника:

var sourceWidth = Math.min(200, imageElement.naturalWidth);
var sourceHeight = Math.min(200, imageElement.naturalHeight);

malloc4k ответ ссылается на это, однако он предположил, что это потому, что image.width был равен нулю. Я добавил этот новый ответ, потому что ширина изображения равна нулю, не обязательно является причиной ошибки в IE.

Ответ 4

Из-за моего опыта, INDEX_SIZE_ERR в IE (даже версия 10), скорее всего, произойдет, когда вы работаете на холсте, который был обработан с помощью drawImage() с неправильным размером клипа.

И если вы загрузили свое изображение динамически, то вполне вероятно, что значения image.width и image.height являются ==0, поэтому вы вызываете

ctx.drawImage(compositeImage, 0, 0, 0, 0, ...

В моем случае решение (работало) заключалось в том, чтобы вместо этого использовать image.naturalWidth и image.naturalHeight.