将图像从 webgl 复制到 2D 画布会丢失 Safari 中的显示 P3 颜色配置文件

问题描述 投票:0回答:1

我在使用 Safari 时遇到一个奇怪的问题,即将图像从 webgl 移动到 2d 不尊重显示 P3 颜色配置文件。它在 Chrome 中运行良好。 任何帮助将不胜感激。

这是代码。

  function copyGLto2D() {
    
    const canvasGL = document.getElementById('webgl')
    const glP3 = canvasGL.getContext('webgl2');
    if (`drawingBufferColorSpace` in glP3) {
      glP3.drawingBufferColorSpace = 'display-p3';
      glP3.clearColor(1, 0, 0, 1);
      glP3.clear(glP3.COLOR_BUFFER_BIT);
    } 
    else return console.warn('browser does not support drawingBufferColorSpace')

    var pixel = new Uint8Array(4)
    glP3.readPixels(0, 0, 1, 1, glP3.RGBA, glP3.UNSIGNED_BYTE, pixel);

    var canvas = document.getElementById('2dP3')
    var ctx = canvas.getContext('2d',{ colorSpace: "display-p3" })
    ctx.drawImage(canvasGL,0,0)
    var pixel2 = ctx.getImageData(0, 0, 1, 1)//, { colorSpace: "display-p3" })
    pixel2 = [pixel2.data[0],pixel2.data[1],pixel2.data[2],pixel2.data[3]]

    console.log(glP3.drawingBufferColorSpace,'>>',ctx.getContextAttributes().colorSpace);
    console.log(pixel.toString(),'>>',pixel2.toString());
  }

  copyGLto2D()
<canvas id="webgl" width=100 height=100></canvas> 
<canvas id="2dP3" width=100 height=100></canvas>

javascript html canvas colors webgl
1个回答
0
投票

同时我找到了 Safari 的修复程序。显然 ctx.drawImage() 有一个错误。这是解决方法(基本上是 gl.readPixels() -> ctx.createImageData() -> ctx.putImageData() )以供将来参考:

function copyGLto2Dv2() {
    const canvasGL = document.getElementById('webgl')
    const glP3 = canvasGL.getContext('webgl2',{preserveDrawingBuffer: true});
    if (`drawingBufferColorSpace` in glP3) {
        glP3.drawingBufferColorSpace = 'display-p3';
        glP3.clearColor(1, 0, 0, 1);
        glP3.clear(glP3.COLOR_BUFFER_BIT);
    } 
    else return console.warn('browser does not support drawingBufferColorSpace')

    var size = canvasGL.width * canvasGL.height * 4;
    var pixels = new Uint8Array(size);
    glP3.readPixels(0, 0, canvasGL.width, canvasGL.height, glP3.RGBA, glP3.UNSIGNED_BYTE, pixels);

    var canvas = document.getElementById('2dP3');
    var ctx = canvas.getContext('2d',{ colorSpace: "display-p3" });
    var data = ctx.createImageData(canvas.width, canvas.height);
    for (var i = 0; i < size; i++) {
        data.data[i] = pixels[i];
    }
    ctx.putImageData(data, 0, 0);

    //CHECK PIXEL RGB
    var pixel = new Uint8Array(4)
    glP3.readPixels(0, 0, 1, 1, glP3.RGBA, glP3.UNSIGNED_BYTE, pixel);
    var pixel2 = ctx.getImageData(0, 0, 1, 1);
    pixel2 = [pixel2.data[0],pixel2.data[1],pixel2.data[2],pixel2.data[3]];

    console.log(glP3.drawingBufferColorSpace,'>>',ctx.getContextAttributes().colorSpace);
    console.log(pixel.toString(),'>>',pixel2.toString());
}
copyGLto2Dv2()
<canvas id="webgl" width=100 height=100></canvas> 
<canvas id="2dP3" width=100 height=100></canvas>

© www.soinside.com 2019 - 2024. All rights reserved.