Почему нет ссылки на данные изображения?

Да, я знаю о .getImageData()

Я имею в виду, скажем, мне нужно изменить некоторые пиксели:

var imageData = ctx.getImageData(...);

Кажется, этот метод дает мне совершенно новую копию "настоящих" (спрятанных где-то глубоко от меня) изображений-данных. Я говорю это, потому что если вы создадите новый:

var imgData2 = ctx.getImageData(.../*same parameters as before*/);

и сравните два буфера:

imageData.data.buffer === imgData2.data.buffer; //false

Таким образом, каждый раз он создает новую копию из своего растрового изображения. Боже мой, почему? Хорошо, идем дальше:

/*...apply some new changes to the imageData in a loop...*/

Ничего особенного сверху. Но теперь пришло время вернуть это:

ctx.putImageData(imageData, ...);

И этот внутри себя запускает новый цикл и копирует мои данные изображения.

Столько дополнительной работы! Есть ли способ получить фактические данные изображения и манипулировать ими без получения/ввода? А если нет - еще раз спрашиваю - ПОЧЕМУ? Это из соображений безопасности? Чего они боятся, что я могу сделать с этими пикселями?

Благодарю вас!


person Kurz    schedule 19.09.2015    source источник
comment
Вы можете поместить двоичные данные в файловый контейнер, обычно используемый для хранения изображений. Если вы затем вызовете getImageData на холсте с этим изображением, нарисованным на нем, вы получите данные о пикселях. Если вы затем превратите эти двоичные значения обратно в символы, вы сможете хранить javascript внутри изображений. Вы можете нанести очень много вреда с помощью javascript, который трудно изучить.   -  person enhzflep    schedule 19.09.2015
comment
просто ответьте на вопрос: почему [1, 2, 3] !== [1, 2, 3] ?   -  person micnic    schedule 19.09.2015
comment
@micnic, пожалуйста, посмотрите внимательно, я говорю о другом, я ожидаю, что два буфера из одного источника должны быть равны по ссылке! Другими словами: var a = []; вар б = а; а === б;   -  person Kurz    schedule 19.09.2015
comment
@micnic и я цитирую: есть ли способ получить фактические данные изображения и манипулировать ими без get/put? А если нет - еще раз спрашиваю - ПОЧЕМУ? Это из соображений безопасности? Чего они боятся, что я могу сделать с этими пикселями? - Это a === b даже не относится к делу и не является вопросом, на который нужно было ответить.   -  person somethinghere    schedule 19.09.2015


Ответы (1)


Короткий ответ:
Нет.

Не так долго Ответ:
Вы можете добиться этого с помощью несколько хаков, но это было бы очень больно.

Пояснения:
Согласно спецификациям, getImageData возвращает TypedArray, который содержит данные изображения холста, а не указатель на live imageData в качестве изменяемого объекта.

Чтобы рисовать на холсте, вы должны использовать такие методы, как fill, stroke, drawImage или putImageData; еще меньше смысла в том, что каждый раз, когда вы перебираете массив, фактическое изображение холста изменяется.

Каждый раз, когда вы вызываете getImageData, создается новый TypedArray (обратите внимание, что выбор фактического типа зависит от UA) создается и заполняется текущими данными canvasImage. Таким образом, вы можете вызвать этот метод, внести различные изменения в ArrayBuffer, не изменяя фактическое изображение на холсте (чтобы вы могли сохранить его или снова вызвать метод).

Что касается того, почему буфер возвращаемых ImageData не одинаков при каждом вызове, я думаю, это потому, что «пиксели должны быть возвращены как альфа-значения без предварительного умножения», но для выступлений они сохраняют его как предварительно умноженное. Вы можете увидеть здесь удаление предварительного умножения из исходного кода Firefox, который фактически заполняет новый Uint8ClampedArray.
Кроме того, он позволяет избежать проверки того, был ли изменен canvasImage с момента последнего вызова, и гарантирует, что вы всегда получаете его текущие ImageData.

person Kaiido    schedule 21.09.2015