Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/437.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么将gl.texImage2D中的格式设置为gl.LUMINANCE而不是gl.RGB会使画布上生成的blob的文件大小仅减小约5%?_Javascript_Webgl - Fatal编程技术网

Javascript 为什么将gl.texImage2D中的格式设置为gl.LUMINANCE而不是gl.RGB会使画布上生成的blob的文件大小仅减小约5%?

Javascript 为什么将gl.texImage2D中的格式设置为gl.LUMINANCE而不是gl.RGB会使画布上生成的blob的文件大小仅减小约5%?,javascript,webgl,Javascript,Webgl,在探索javascript时,我遇到了一个相当令人困惑的问题。前言是:我使用ImageBitmap接口将不同mime类型(主要是PNG/JPG)的图像转换为位图,然后将它们传输给worker,在单独的线程中将其转换为blob(为此,我首先将它们绘制到屏幕外的画布上下文中),然后保存到IDB,同时主线程继续加载新图像。在这样做的同时,为了拓宽我的视野,我决定在画布中使用webgl2渲染上下文,因为GL是我从未接触过的东西 为了将位图应用到画布,我使用了texImage2D函数,我似乎不明白这一点。

在探索javascript时,我遇到了一个相当令人困惑的问题。前言是:我使用ImageBitmap接口将不同mime类型(主要是PNG/JPG)的图像转换为位图,然后将它们传输给worker,在单独的线程中将其转换为blob(为此,我首先将它们绘制到屏幕外的画布上下文中),然后保存到IDB,同时主线程继续加载新图像。在这样做的同时,为了拓宽我的视野,我决定在画布中使用webgl2渲染上下文,因为GL是我从未接触过的东西

为了将位图应用到画布,我使用了texImage2D函数,我似乎不明白这一点。在那里,我可以指定内存中存储的数据的格式(应该是rgb(对吗?),因为位图是在没有alpha预乘的情况下创建的)、内部格式和类型。由于format/internalformat/type的组合是由spec指定的,因此我试图利用它们的众多特性,并为我的目的选择了最好的(质量/文件大小)。由于转换为位图的图像大部分是黑白的,所以我认为亮度是我所需要的。但首先我使用了标准RGB格式:

gl.texImage2D(
    gl.TEXTURE_2D, 0, gl.RGB, bitmap.width, bitmap.height, 0, gl.RGB, gl.UNSIGNED_BYTE, bitmap
);
然后我将RGB565与无符号的_SHORT_5_6_5数据类型一起使用,没有发现任何质量损失,而blob大小比RGB减少了约30%。我的理解是,它减少了,因为RGB565是每像素2个无符号短字节,对吗?然后我使用了无符号的_SHORT_5_5_5_1 RGBA,与标准RGB相比,blob文件大小减少了约43%。甚至低于RGB565!但是图像上的渐变变得不稳定,所以我没有5551RGBA。5551 RGBA和RGB565在尺寸上的巨大差异是我不理解的。更令人困惑的是,当根据类型/格式/内部格式组合使用亮度时,与标准RGB相比仅减少约5%。为什么RGB565将百日咳的体型缩小了约30%,而luma的体型缩小了约5%

对于所有这些,我在片段着色器中使用了相同的浮点采样器:

 #version 300 es
 precision mediump float;
 precision mediump sampler2D;

 uniform sampler2D sampler;
 uniform vec2 dimensions;

 out vec4 color;

 void main(){
      color = texture(sampler, vec2(gl_FragCoord.x/dimensions.x, 1.0 - (gl_FragCoord.y/dimensions.y)));
 }
同样的pixelStorei和texParameteri:

gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
如下面的代码片段所示,如果图像是黑白的,则luma不会更改blob的文件大小,而如果图像是彩色的,则会明显减小,尽管仍然比RGBA4小。考虑到RGBA4每像素有2个字节,而LUMA-1,这与直观性相当矛盾。
(异步()=>{
函数createImage(src){
返回新承诺((rs,rj)=>{
var img=新图像();
img.crossOrigin='匿名';
img.src=src;
img.onload=()=>rs(img);
img.onerror=e=>rj(e);
});
};
var jpeg=wait createImage('https://upload.wikimedia.org/wikipedia/commons/a/aa/5inchHowitzerFiringGallipoli1915.jpeg');
var png=await createImage('https://upload.wikimedia.org/wikipedia/commons/2/2c/6.d%C3%ADl_html_m2fdede78.png');
var jpgClr=wait createImage('https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/%22Good_bye%2C_sweetheart%22%2C_tobacco_label%2C_ca._1865.jpg/117px-%22再见%2C_甜心%22%2C_烟草标签%2C_ca._1865.jpg');
变量格式={
标准:{
内部格式:“RGB8”,
格式:“RGB”,
类型:“无符号字节”,
},
rgb565:{
内部格式:“RGB565”,
格式:“RGB”,
类型:“未签名的\u短\u 5\u 6\u 5”,
},
rgb9e5:{
内部格式:“RGB9_E5”,
格式:“RGB”,
类型:“FLOAT”,
},
srgb:{
内部格式:“SRGB8”,
格式:“RGB”,
类型:“无符号字节”,
},
rgba32f:{
内部格式:“RGB32F”,
格式:“RGB”,
类型:“FLOAT”,
},
rgba4:{
内部格式:“RGBA4”,
格式:“RGBA”,
键入:“未签名的_短_4_4_4_4”,
},
rgb5a1:{
内部格式:“RGB5_A1”,
格式:“RGBA”,
键入:“未签名的_短_5_5_5_1”,
},
卢马:{
内部格式:“亮度”,
格式:“亮度”,
类型:“无符号字节”,
},
};
函数compareFormatSize(图像){
返回新承诺((r,))=>{
创建图像位图(图像{
前多重耶尔法:“无”,
colorSpaceConversion:“无”,
})。然后(异步位图=>{
var text=String(image.src.match(/(?compareFormatSize(png))。然后(=>compareFormatSize(jpgClr));
函数logBlobSize(位图,{internalFormat,format,type}){
返回新承诺(r=>{
drawCanvas(位图,内部格式,格式,类型).convertToBlob({
类型:`image/webp`
}).then(blob=>{console.log(`blob from${internalFormat}是${blob.size}b`);r();});
})
}
函数drawCanvas(位图、内部格式、格式、类型){
const gl=(新的OffscreenCanvas(bitmap.width,bitmap.height)).getContext(“webgl2”{
反别名:假,
阿尔法:错,
深度:假,
});
函数createShader(gl、类型、glsl){
常量着色器=gl.createShader(类型);
gl.shaderSource(着色器,glsl)
gl.compileShader(着色器);
if(!gl.getShaderParameter(着色器,gl.COMPILE_状态)){
console.error(gl.getShaderInfoLog(着色器));
gl.deleteShader(着色器);
返回;
}
返回着色器;
}
const vs=createShader(
德国劳埃德船级社,
gl.VERTEX_着色器,
`#300版es
#定义位置\u位置0
vec2位置的布局(位置=位置\位置);
void main()
{
gl_位置=vec4(位置,0.0,1.0);
}`,
);
常量fs=createShader(
德国劳埃德船级社,
gl.FRAGMENT_着色器,
`#300版es
精密中泵浮子;
精密mediump取样器2D;
均匀取样器;
二维均匀矢量;
输出vec4颜色;
void main()
{
颜色=纹理(取样器,vec2(gl_FragCoord.x/dimensions.x,1.0-(gl_FragCoord.y/dimensions.y));
}`,
);
const program=gl.createProgram();
总分类:attachShader(项目,vs);
德国劳埃德大学附属医院(p