【问题标题】:Recolour Icon like Google Earth像 Google 地球一样重新着色图标
【发布时间】:2016-02-11 21:45:22
【问题描述】:

KML 允许您为图标指定<color>

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
  <Placemark>
    <name>Pin</name>
    <Point>
      <coordinates>0, 0</coordinates>
    </Point>
    <Style>
      <IconStyle>
        <color>ff8c4800</color>
        <scale>10</scale>
        <Icon>
          <href>http://maps.google.com/mapfiles/kml/pushpin/wht-pushpin.png</href>
        </Icon>
      </IconStyle>
    </Style>
  </Placemark>
</kml>

我正在尝试使用 Porter-Duff 颜色混合方法在 Go 中做同样的事情。

    // blendColors uses the Porter-Duff over method
    // for combing two colors with alpha channels
    func blendColors(c1 color.Color, c2 color.Color) color.Color {
        r1, g1, b1, a1 := extractComponents(c1)
        r2, g2, b2, a2 := extractComponents(c2)
        var (
            a = a1 + a2*(1.0-a1)
            r = (r1*a1 + r2*a2*(1.0-a1)) / a
            g = (g1*a1 + g2*a2*(1.0-a1)) / a
            b = (b1*a1 + b2*a2*(1.0-a1)) / a
        )
        return color.RGBA{
            R: clampColorValue(int(r)),
            G: clampColorValue(int(g)),
            B: clampColorValue(int(b)),
            A: clampColorValue(int(a * 255)),
        }
    }

查看完整代码here

以下是一些具有不同不透明度级别(从 0 到 255)的输出示例。

  • 0

  • 100

  • 200

  • 255

这些并不令人满意(由于锯齿状边缘和褪色的黑色边框),我想知道我应该采取什么方法来获得更类似于 Google 地球所做的结果。

【问题讨论】:

  • 源像素是否预乘了 alpha?我可以想象这方面的不一致会导致锯齿状边缘和黑色像素的着色。
  • 不确定你所说的预乘是什么意思。
  • 如果我有一个 alpha 为 0.5 的白色像素,有两种常用的方式来表示它(假设 8 位 RGBA):(255, 255, 255, 128)(128, 128, 128, 128)。第二种方式称为“预乘”,因为 R、G 和 B 值已经被 alpha 缩放(乘)了。您必须知道您的源是否被预乘以正确操作像素(以及您的输出是否期望它们被预乘)。否则,您最终可能会遇到帖子显示的问题。
  • 感谢您的解释。文档说它是预乘的golang.org/pkg/image/color/#Color

标签: go colors google-earth alphablending


【解决方案1】:

我设法使用两个技巧修复了输出。

  1. 如果原始像素没有 100% 的 alpha,请不要触摸它。这修复了锯齿状的边缘。如果我不想这样做,我想我必须实现某种类型的抗锯齿。

  2. 使用原始像素颜色的灰度来确定要混合的颜色的 Alpha。

这是我修改后的混合代码。

    // blendColors uses the Porter-Duff over method
    // for combing two colors with alpha channels
    func blendColors(c1 color.Color, original color.Color) color.Color {
        r1, g1, b1, _ := extractComponents(c1)
        r2, g2, b2, a2 := extractComponents(original)

        // use the origial color's greyscale value to calculate
        // how much of the new color to use
        a1 := float64(color.GrayModel.Convert(original).(color.Gray).Y) / 255

        // don't do any blending if the original pixels
        // alpha isn't 100%
        if int(a2) == 0 {
            return original
        }

        var (
            a = a1 + a2*(1.0-a1)
            r = (r1*a1 + r2*a2*(1.0-a1)) / a
            g = (g1*a1 + g2*a2*(1.0-a1)) / a
            b = (b1*a1 + b2*a2*(1.0-a1)) / a
        )
        return color.RGBA{
            R: clampColorValue(int(r)),
            G: clampColorValue(int(g)),
            B: clampColorValue(int(b)),
            A: clampColorValue(int(a * 255)),
        }
    }

编辑:要求 alpha 为 100% 并不总是有效。我最终使用了alpha &lt; 0.3 阈值。

【讨论】:

    猜你喜欢
    • 2021-06-21
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 2022-01-09
    • 2015-06-09
    相关资源
    最近更新 更多