Javascript html图像的压缩

Javascript html图像的压缩,javascript,html,image,compression,webgl,Javascript,Html,Image,Compression,Webgl,我想使用从WebGL中的服务器检索的base64编码png。 为此,我将编码的png加载到html图像对象中。 对于我的应用程序,我需要png数据是绝对无损的,但是着色器检索到的像素值在不同的浏览器中是不同的。。。 (如果我将图像加载到画布中并使用getImageData,检索到的像素值在不同浏览器中也不同)。 一定有一些奇怪的像素值过滤/压缩发生,但我不知道如何和为什么。有人熟悉这个问题吗 正在从服务器加载映像: var htmlImage = new Image(); htmlImage.s

我想使用从WebGL中的服务器检索的base64编码png。 为此,我将编码的png加载到html图像对象中。 对于我的应用程序,我需要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); 
尝试使用画布读取像素值(不同浏览器的不同值):


正如@Sergiu指出的,默认情况下,浏览器可以对图像应用颜色校正、gamma校正、颜色配置文件或其他任何内容

在WebGL中,您可以关闭此功能。在将图像上载到纹理调用之前,请使用
gl.pixelStorei
解压缩\u COLORSPACE\u CONVERSION\u WEBGL并将其传递给
gl\u NONE
,如中所示

gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
这将告诉浏览器不要应用颜色空间、gamma等。这对WebGL很重要,因为许多3D应用程序使用纹理传递图像以外的内容。示例包括法线贴图、高度贴图、环境光遮挡贴图、辉光贴图、镜面反射贴图和许多其他类型的数据

默认设置为

gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.BROWSER_DEFAULT_WEBGL);
注意,这可能仅在直接从图像获取数据时有效,而在通过2d画布传递图像时无效

请注意,如果您是通过将数据绘制到二维画布来从WebGL画布获取数据,则所有赌注都是无效的。如果没有其他内容,则画布2D使用预乘alpha,因此如果alpha<255,则将数据复制到2D画布中或从2D画布中复制数据总是有损的。如果您希望返回的数据不受2D画布的影响,请使用
gl.readPixels

请注意,此方法的一个潜在问题是速度。当您下载图像时,浏览器可能会假定图像最终会显示出来。它无法预先知道它将在纹理中使用。因此,您创建一个图像标记,设置src属性,浏览器下载图像,解压缩图像,准备显示,然后发出加载事件,然后使用
UNPACK\u COLORSPACE\u CONVERSION\u WEBGL=NONE
将图像上载到纹理。如果浏览器没有保留一个尚未应用颜色空间转换的版本,此时可能需要重新解压缩。这可能不是一个明显的速度问题,但也不是零

为了解决这个问题,浏览器添加了。这个API解决了一些问题

  • 它可以在web worker中使用,因为它不像Image那样是DOM元素

  • 你可以给它传递一个子矩形,这样你就不必首先得到整个图像,最终得到它的某个部分

  • 在开始避免上述问题之前,您可以告诉它是否应用颜色空间校正


  • 不幸的是,截至2018/12年,它只得到了Chrome的完全支持。Firefox有部分支持。Safari没有。

    这是意料之中的:可能的副本非常有用,非常感谢您的详细回答!我使用UNPACK\u COLORSPACE\u CONVERSION\u WEBGL属性解决了我的问题,如您所说:)
    gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.BROWSER_DEFAULT_WEBGL);