Странное сжатие HTML-изображения - PullRequest
0 голосов
/ 10 декабря 2018

Я хочу использовать 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;   

1 Ответ

0 голосов
/ 10 декабря 2018

Как указывает @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);

Обратите внимание, что это работает, только когдабрать данные непосредственно с изображения, а не при прохождении изображения через 2-й холст.

Обратите внимание, что если вы получаете данные из холста WebGL путем их рисования на 2D-холсте, все ставки отключены.Если ничто иное, Canvas 2D использует предварительно умноженную альфа, поэтому копирование данных в 2D холст и из него всегда происходит с потерями, если альфа <255. Используйте <code>gl.readPixels, если вы хотите, чтобы данные не подвергались влиянию 2D холста.

Обратите внимание, что одной потенциальной проблемой этого метода является скорость.При загрузке изображения браузер, вероятно, предполагает, что оно в конечном итоге будет отображаться.Он не может заранее знать, что он будет использоваться в текстуре.Итак, вы создаете тег изображения, устанавливаете атрибут src, браузер загружает изображение, распаковывает его, подготавливает его к отображению, затем генерирует событие загрузки, затем вы загружаете это изображение в текстуру с помощью UNPACK_COLORSPACE_CONVERSION_WEBGL = NONE.Браузеру на этом этапе, возможно, придется повторно распаковать его, если он не поддерживает версию, в которой уже не применено преобразование цветового пространства.Это вряд ли заметная проблема со скоростью, но она также не равна нулю.

Чтобы обойти это, браузеры добавили ImageBitmap api .Этот API-интерфейс решает несколько проблем.

  1. Он может использоваться веб-работником, поскольку он не является элементом DOM, например, Image is

  2. .передайте его под прямоугольником, чтобы вам не нужно было сначала получать все изображение, чтобы получить какую-то часть, если оно

  3. Вы можете указать, применять ли коррекцию цветового пространства доон начинает избегать проблемы, упомянутой выше.

К сожалению, по состоянию на 2018/12 он полностью поддерживается только Chrome.Firefox имеет частичную поддержку.У Safari нет ни одного.

...