【问题标题】:Gamma Adjustment on the HTML5 Canvas?HTML5 Canvas 上的 Gamma 调整?
【发布时间】:2019-01-04 04:56:43
【问题描述】:

我找到了增加伽玛的方法,但没有办法减少它! This article 说明了增加伽玛的公式。该公式适用于增加伽玛,但不适用于减少,即使我将减少应用于画布的新实例。我尝试重新绘制画布并使用负值进行 gamma 计算,但我没有取回原来的画布。

//For increasing, I tried
gamma = 0.5;
gammacorrection = 1/gamma;
r = Math.pow(255 * (r / 255), gammacorrection);
g = ...
b = ...

//For decreasing
gamma = -0.5;
gammacorrection = 1/gamma;
r = Math.pow(255 * (r / 255), gammacorrection);
g = ...
b = ...

第一部分有效。第二个没有。

【问题讨论】:

    标签: html5-canvas


    【解决方案1】:

    没有负伽玛校正。您应该保存原始值并在进行 gamma 更改时使用它们,并将 gamma 设置为 1.0 以恢复原始值。

    另请注意,您的运算顺序错误(指数在乘法之前)。

    var originals = { r: r, g: g, b: b };
    
    // increase
    gamma = 0.5;
    gammacorrection = 1/gamma;
    r = 255 * Math.pow(( originals.r / 255), gammacorrection);
    g = ...
    b = ...
    
    // revert to original
    gamma = 1;
    gammacorrection = 1/gamma;
    r = 255 * Math.pow(( originals.r / 255), gammacorrection);
    g = ...
    b = ...
    

    【讨论】:

    • 是的,@JJJ 给出了一个连续函数。这应该是公认的答案,因为数学实际上是正确的。
    【解决方案2】:

    为了完整起见,这里有一段工作代码

    async function adjustGamma(gamma) {
        const gammaCorrection = 1 / gamma;
        const canvas = document.getElementById('canvasOutput');
        const ctx = canvas.getContext('2d');
        const imageData = ctx.getImageData(0.0, 0.0, canvas.width, canvas.height);
        const data = imageData.data;
        for (var i = 0; i < data.length; i += 4) {
            data[i] = 255 * Math.pow((data[i] / 255), gammaCorrection);
            data[i+1] = 255 * Math.pow((data[i+1] / 255), gammaCorrection);
            data[i+2] = 255 * Math.pow((data[i+2] / 255), gammaCorrection);
        }
        ctx.putImageData(imageData, 0, 0);
    }
    

    这里的函数根据 OP 链接的文章中的公式在 ID 为“canvasOutput”的 Canvas 上调整 gamma

    【讨论】:

    • 感谢您回答一个 6 岁的问题! :) 我已经根据上述解决方案解决了这个问题,但我感谢您的贡献。
    【解决方案3】:

    伽玛没有负值。理想情况下,该值将介于0.017.99 之间。因此,应该可以通过使用图像的原始值创建一个新的画布实例,然后实例化它,或者通过使用原始图像创建一个像素池并恢复它来将伽玛恢复到原始值。

    我写了一个脚本,我将如何构建减少伽马的算法。

    var gamma = 0.5;
    var gammaCorrection = 1 / gamma;
    
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var imageData = ctx.getImageData(0.0, canvas.width, canvas.height);   
    
    function GetPixelColor(x, y) {   
        var index = parseInt(x + canvas.width * y) * 4;
        var rgb = {
            r : imageData.data[index + 0],
            g : imageData.data[index + 1],
            b : imageData.data[index + 2]
        };
    
        return rgb;
    }
    
    function SetPixelColor(x, y, color) {
        var index = parseInt(x + this.width * y) * 4;
        var data = imageData.data;
    
        data[index+0] = color.r;
        data[index+1] = color.g;
        data[index+2] = color.b;
    };
    
    
    for (y = 0; y < canvas.height; y++) {
         for (x = 0; x < canvas.width; x++) {
             var color = GetPixelColor(x, y)
             var newRed   = Math.pow(255 * (color.r / 255), gammaCorrection);
             var newGreen = Math.pow(255 * (color.g / 255), gammaCorrection);
             var newBlue  = Math.pow(255 * (color.b / 255), gammaCorrection);
    
             var color = {
                 r: newRed,
                 g: newGreen,
                 b: newBlue
             }
    
             SetPixelColor(x, y, color);
         }
    }
    

    我不知道应用程序应该如何调整伽玛值,但我想它是通过值调整器完成的。如果是这样,您应该动态调整伽马值,给出最小和最大范围。我没有测试代码,这不是我的范围,但希望这个想法很清楚。

    编辑: 先了解伽玛校正原理,不如先定义伽玛。

    伽玛是改变像素输入的显示器特性。 Gamma 校正是反转线性 RGB 值的过程,以使最终输出保持线性。例如,如果您计算出的对象的光强度为 0.5,则不会将结果存储为像素中的 0.5。将其存储为pow(0.5, 1.0/2.2) = 0.73。当您将 0.73 发送到监视器时,它将对该值应用伽马并产生 pow(0.73, 2.2) = 0.5,这就是您想要的。为此,您需要应用反伽马函数。

    o=pow(i, 1.0/gamma)

    在哪里

    o 是输出值。

    i 是输入值。

    gamma 是显示器使用的伽玛值。

    因此,伽马校正只不过是输入值上升到伽马倒数的幂。因此,要将 gamma 恢复到原始值,请在应用 gamma 校正之前应用公式。

    蓝线表示在将像素发送到显示器之前需要应用到像素的逆伽马曲线。当您的显示器将其伽马曲线(红线)应用于像素时,结果是一条线性线(绿线),代表您预期的 RGB 像素值。

    【讨论】:

    • 我正在创建一个新的画布实例,并重新绘制了图像!您的代码是否增加/减少 gamma?
    • 如果我通过 0.5 的调整来提高 gamma,下次重绘时如何通过相同的调整来降低它?
    • 谢谢你的解释!它真的很有帮助!对不起,叫我笨蛋或者叫勺子喂食,我还是不明白,我要如何将 0.5 的 gamma 应用于图像并将同一图像(重新绘制全新)的 gamma 降低 0.5 以恢复我的原始图像,因为我想直观地展示它。您能否将其简化为一个简单的增加和减少公式,我可以使用加/减按钮在我的画布上调用它来提高/减少伽玛?
    • 将伽玛设置为初始1 不能解决您的问题?或者换一种说法:如果你有伽玛的初始值,当你用相同的百分比减少它时,用一定的百分比增加它的值不会改变同样数量的输出?
    • 哦,是的,伙计!我将初始伽玛设置为 1,并在我的按钮点击时以 0.1 的上升/下降来操纵该值!将下限保持为 0,将上限保持为 2。效果很好,伙计……非常感谢! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 2014-12-27
    • 1970-01-01
    • 2013-01-04
    相关资源
    最近更新 更多