doufendi9063 2016-02-11 21:45
浏览 82

像Google Earth一样重新着色图标

KML allows you to specify a <color> for an icon.

<?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>

I'm trying to do the same thing in Go using the Porter-Duff colour blending method.

    // 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)),
        }
    }

See full code here

Here are some output examples with different opacity levels (from 0 - 255).

  • 0

  • 100

  • 200

  • 255

These are not satisfactory (due to the jagged edges and faded black border) and I want to know what approach I should take to get results more akin to what Google Earth does.

  • 写回答

1条回答 默认 最新

  • dongzhiman2162 2016-02-12 16:01
    关注

    I managed to fix the output using two tricks.

    1. If the original pixel doesn't have 100% alpha, don't touch it. This fixes the jagged edges. If I didn't want to do this, I think I'd have to implement some type of anti-aliasing.

    2. Use the grayscale of the original pixel color to determine the alpha of the color that's being blended in.

    Here's my revised blending code.

        // 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)),
            }
        }
    

    edit: Requiring alpha to be 100% doesn't work well all the time. I ended up using a alpha < 0.3 threshold.

    评论

报告相同问题?

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?