【问题标题】:Computing "average" of two colors计算两种颜色的“平均值”
【发布时间】:2010-12-30 22:42:17
【问题描述】:

这只是略微与编程相关 - 与颜色及其表示还有更多工作要做。

我正在开发一个非常低级的应用程序。我在内存中有一个字节数组。那些是字符。它们使用抗锯齿进行渲染:它们的值从 0 到 255,0 表示完全透明,255 表示完全不透明(alpha,如果你愿意的话)。

我在构思渲染此字体的算法时遇到了麻烦。我正在为每个像素执行以下操作:

            // intensity is the weight I talked about: 0 to 255
            intensity = glyphs[text[i]][x + GLYPH_WIDTH*y];
            if (intensity == 255)
                continue; // Don't draw it, fully transparent
            else if (intensity == 0) 
                setPixel(x + xi, y + yi, color, base); // Fully opaque, can draw original color
            else { // Here's the tricky part
                // Get the pixel in the destination for averaging purposes
                pixel = getPixel(x + xi, y + yi, base);
                // transfer is an int for calculations
                transfer = (int)  ((float)((float) (255.0 - (float) intensity/255.0) * (float) color.red + (float) pixel.red)/2); // This is my attempt at averaging
                newPixel.red = (Byte) transfer;
                transfer = (int)  ((float)((float) (255.0 - (float) intensity/255.0) * (float) color.green + (float) pixel.green)/2);
                newPixel.green = (Byte) transfer;
                // transfer = (int) ((float) ((float) 255.0 - (float) intensity)/255.0 * (((float) color.blue) + (float) pixel.blue)/2);
                transfer = (int)  ((float)((float) (255.0 - (float) intensity/255.0) * (float) color.blue + (float) pixel.blue)/2);
                newPixel.blue = (Byte) transfer;
                // Set the newpixel in the desired mem. position
                setPixel(x+xi, y+yi, newPixel, base);
            }

如您所见,结果并不理想。这是一个非常放大的图像,在 1:1 的比例下,看起来文本有一个绿色的“光环”。

任何关于如何正确计算它的想法将不胜感激。

感谢您的宝贵时间!

【问题讨论】:

    标签: c low-level antialiasing alphablending


    【解决方案1】:

    您需要混合背景色和前景色。阿拉:

    pixelColour = newColour * intensity + backgroundColour * (1 - intensity)
    

    顺便说一句,这是一种非常缓慢的渲染和混合字体的方式。您应该改为将字体的所有字符渲染到具有您需要的所有属性的屏幕外表面,然后在需要文本时将其用作纹理以渲染到其他表面。

    编辑:

    这看起来不对:

    (255.0 - (float) intensity/255.0)
    

    应该是:

    (255.0 - (float) intensity)/255.0
    

    【讨论】:

    • 或者,用原代码的话来说:transfer = (int) ((1.0 - intensity/255.0) * color.red + intensity/255.0 * pixel.red);
    • P.S. “将字体的所有字符渲染到屏幕外的表面” - 我认为这就是 glyphs 的含义。
    • 我不太关心性能,因为这是一个概念验证的学术应用程序。但感谢您的意见!我会试试的。
    【解决方案2】:

    我相信“光环”是由抗锯齿引起的。该技术将像素与其相邻像素进行平均。

    我知道您似乎没有使用 OpenGL,但this chapter 可能有助于解释一些理论。希望我有一个更好的答案,但希望这能为您指明正确的方向。我的第一次尝试是禁用抗锯齿,因为它似乎弊大于利。可能还有比这更好的解决方案。

    【讨论】:

      【解决方案3】:

      由于当前像素值会修改下一个像素值,因此逐个像素地进行 Alpha 混合可能太复杂了。

      我会重新设计算法,考虑框式混合。


      由于许多 getPixel 调用单个字形,您无法生成正确的目标图像。

      【讨论】:

        猜你喜欢
        • 2014-06-19
        • 2011-05-30
        • 2010-11-07
        • 2011-12-04
        • 2016-08-16
        • 2023-03-14
        • 2013-08-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多