Я хочу использовать png-файл с кодировкой base64, который я получаю с сервера в WebGL. Для этого я загружаю закодированный png в объект HTML Image. Для моего приложения мне нужно, чтобы данные png были абсолютно без потерь, но значения пикселей, полученные шейдером, различаются в разных браузерах ... (если я загружаю изображение на холст и использую getImageData, полученные значения пикселей также различаются в разных браузерах). Должна быть какая-то странная фильтрация / сжатие значений пикселей, но я не могу понять, как и почему. Кто-нибудь знаком с этой проблемой?
Загрузка изображения с сервера:
var htmlImage = new Image();
htmlImage.src = BASE64_STRING_FROM_SERVER
Загрузка изображения в шейдер:
ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGB, ctx.RGB, ctx.UNSIGNED_BYTE,
htmlImage);
Попытка прочитать значения пикселей с помощью холста (разные значения в браузерах):
var canvas = document.createElement('canvas');
canvas.width = htmlImage.width;
canvas.height = htmlImage.height;
canvas.getContext('2d').drawImage(htmlImage, 0, 0, htmlImage.width,
htmlImage.height);
// This data is different in, for example, the latest version of Chrome and Firefox
var pixelData = canvas.getContext('2d').getImageData(0, 0,
htmlImage.width, htmlImage.height).data;
Возможный дубликат Является ли метод холста getImageData зависимым от машины / браузера?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Как указывает @Sergiu, по умолчанию браузер может применять к изображениям цветокоррекцию, гамма-коррекцию, цветовые профили или что-то еще.
В WebGL это можно отключить. Перед загрузкой изображения в текстуру вызовите gl.pixelStorei с gl.UNPACK_COLORSPACE_CONVERSION_WEBGL и передайте ему gl_NONE, как в
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
Это укажет браузеру не применять цветовые пространства, гамму и т. д. Это было важно для WebGL, потому что многие 3D-приложения используют текстуры для передачи вещей, отличных от изображений. Примеры включают в себя карты нормалей, карты высот, карты окклюзии окружающей среды, карты свечения, карты отражений и многие другие типы данных.
По умолчанию установлено
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.BROWSER_DEFAULT_WEBGL);
Обратите внимание, что это, вероятно, работает только при получении данных непосредственно из изображения, а не при передаче изображения через 2d холст.
Обратите внимание: если вы получаете данные с холста WebGL, рисуя их на 2D-холсте, то все ставки отключены. Во всяком случае, в 2D-холсте используется предварительно умноженная альфа, поэтому копирование данных в 2D-холст и из него всегда происходит с потерями, если альфа <255. Используйте gl.readPixels, если вы хотите, чтобы данные не пострадали от каких-либо действий 2D-холста.
Обратите внимание, что одна из потенциальных проблем этого метода - скорость. Браузер, вероятно, предполагает, что когда вы загружаете изображение, оно в конечном итоге будет отображаться. У него нет возможности заранее узнать, что он будет использоваться в текстуре. Итак, вы создаете тег изображения, устанавливаете атрибут src, браузер загружает изображение, распаковывает его, подготавливает к отображению, затем генерирует событие загрузки, а затем вы загружаете это изображение в текстуру с помощью UNPACK_COLORSPACE_CONVERSION_WEBGL = NONE. Браузеру на этом этапе, возможно, придется повторно распаковать его, если он не сохранил версию, в которой уже не применено преобразование цветового пространства. Это вряд ли заметная проблема со скоростью, но и не ноль.
Чтобы обойти это, браузеры добавили ImageBitmap API. Этот API решает несколько проблем.
Его можно использовать в веб-воркере, потому что это не элемент DOM, как Image.
Вы можете передать ему подпрямоугольник, поэтому вам не нужно сначала получать все изображение, чтобы в конечном итоге получить какую-то часть, если она
Вы можете сказать ему, применять ли коррекцию цветового пространства, прежде чем он начнет избегать проблемы, упомянутой выше.
К сожалению, с 2018/12 года он полностью поддерживается только Chrome. Firefox имеет частичную поддержку. В Safari их нет.
Это очень полезно, спасибо за подробный ответ! Я решил свою проблему с помощью атрибута UNPACK_COLORSPACE_CONVERSION_WEBGL, как вы сказали :)
Ожидается: stackoverflow.com/questions/26615580/…