Chromium не копирует значения массива - PullRequest
1 голос
/ 07 декабря 2010

Я использую Webworker для обработки массива пикселей из Canvas и после возвращения обратно - присваиваю массиву ImageData. Firefox прекрасно работает, но Chromium помещает пустой массив пикселей в Canvas. Расследование показало, что копирование массива не работает, результирующий массив имеет нулевые элементы. Разрезание массива также не помогло, только просмотр каждого элемента с for in помог, но мне интересно, в чем здесь проблема?

imgd = ctx.createImageData(w,h);
worker.onmessage = function (e) {
  imgd.data = e.data; 
  console.log(imgd.data === e.data); // true in FF, false in Chromium  

  img.data = e.data.slice(0); 
  console.log(imgd.data); // correct in FF, empty array in Chromium
};

Ответы [ 3 ]

3 голосов
/ 07 декабря 2010

Chrome:

> var e = document.createElement('canvas').getContext('2d').createImageData(10, 10).data;
undefined
> Object.prototype.toString.call(e)
"[object ImageData]"
> e.slice
undefined

FX4:

>>> var e = document.createElement('canvas').getContext('2d').createImageData(10, 10).data;
undefined
>>> Object.prototype.toString.call(e)
"[object Uint8ClampedArray]"
>>> e.slice
slice()

Opera:

>>> var e = document.createElement('canvas').getContext('2d').createImageData(10, 10).data;
undefined
>>> Object.prototype.toString.call(e)
"[object CanvasPixelArray]"
>>> e.slice
undefined

Это нам что говорит? Ну, спецификация нигде не гласит , что массив данных пикселей должен иметь методы, подобные массиву.

Ergo, используйте .slice, только если доступно, в противном случае сделайте for loop копию, а также протестируйте более чем в 2 браузерах.

0 голосов
/ 09 февраля 2011

Вместо createImageData(), я думаю, вы хотите использовать getImageData(). (Это документация Mozilla, но Chrome также имеет этот метод в контекстах.)

0 голосов
/ 07 декабря 2010

Вызов slice только с параметром запуска является расширением Spidermonkey.Попробуйте вместо этого указать начало и конец:

e.data.slice(0, e.data.length)

Редактировать createImageData возвращает ImageData объект какие атрибуты доступны только для чтения.Так что вы не можете изменить data.Используйте createImageData для создания ImageData объекта в вашем CanvasRenderingContext2D из другого ImageData объекта:

worker.onmessage = function (e) {
    ctx.createImageData(e.data);
};
...