为什么Go';s draw.DrawMask似乎忽略了我的黑白面具?

为什么Go';s draw.DrawMask似乎忽略了我的黑白面具?,go,draw,Go,Draw,我正在尝试为数据和背景渲染符合用户输入颜色的条形码,尽管条形码本身是按预期的黑白颜色生成的,但尝试在“image/draw”的draw.DrawMask函数中使用它们作为遮罩图像会导致源图像完全通过,完全忽略遮罩 这与本文中给出的示例大相径庭 我已经把这个问题简化为一个相当小的例子,一个简单的黑色背景上的白色方块作为面具,以统一的颜色作为来源和目的地,这种行为还在继续。我显然无法理解此函数的某些行为,但试图找到其他人遇到的类似问题似乎都以完全不同的方法结束(例如另一个库来完成此工作),而不是理解

我正在尝试为数据和背景渲染符合用户输入颜色的条形码,尽管条形码本身是按预期的黑白颜色生成的,但尝试在“image/draw”的draw.DrawMask函数中使用它们作为遮罩图像会导致源图像完全通过,完全忽略遮罩

这与本文中给出的示例大相径庭

我已经把这个问题简化为一个相当小的例子,一个简单的黑色背景上的白色方块作为面具,以统一的颜色作为来源和目的地,这种行为还在继续。我显然无法理解此函数的某些行为,但试图找到其他人遇到的类似问题似乎都以完全不同的方法结束(例如另一个库来完成此工作),而不是理解draw.DrawMask使用中的错误

我发布的代码包含一个函数,用于将三个输出图像写入BMP文件,但如果使用任何其他方法将图像数据保存到文件中,则会重复此行为

package main

import (
    "bytes"
    bmp "golang.org/x/image/bmp"
    "image"
    "image/color"
    "image/draw"
    "io/ioutil"
    "os"
)

func main() {
    //Use one rectange to make all new images
    bounds := image.Rect(0, 0, 100, 100)
    //Generate a 20px wide white square in the centre of a black background
    mask := image.NewNRGBA(bounds)
    draw.Draw(mask, bounds, image.NewUniform(color.Black), image.ZP, draw.Src)
    draw.Draw(mask, image.Rect(40, 40, 60, 60), image.NewUniform(color.White), image.ZP, draw.Src)
    //Generate a blue image of the right size - this is unnecessary, but shouldn't hurt
    blue := image.NewNRGBA(bounds)
    draw.Draw(blue, bounds, image.NewUniform(color.NRGBA{B: 255, A: 255}), image.ZP, draw.Src)
    //Copy the blue image into what is the desired output - also unnecessary, but will help to demonstrate each step is working independently
    result := image.NewNRGBA(bounds)
    draw.Draw(result, bounds, blue, image.ZP, draw.Src)
    //Use mask to draw green onto the blue - but only inside the 20px square (in theory)
    draw.DrawMask(result, bounds, image.NewUniform(color.NRGBA{G: 255, A: 255}), image.ZP, mask, image.ZP, draw.Over)

    writeImageToBMP(blue, "blue.bmp")
    writeImageToBMP(mask, "mask.bmp")
    writeImageToBMP(result, "result.bmp")
}

func writeImageToBMP(img image.Image, filename string) {
    //This part isn't relevant to the problem, I just don't know a better way to show content of an image
    var imgBytes bytes.Buffer
    bmp.Encode(&imgBytes, img)
    ioutil.WriteFile(filename, imgBytes.Bytes(), os.ModeExclusive)
}
我希望上面的代码能够生成三个图像:

  • 一个蓝色的正方形,100像素乘以100像素
  • 一个黑色正方形,100px x 100px,中间有一个20px x 20px的白色正方形
  • 一个蓝色正方形,100px x 100px,中间有一个20px x 20px的绿色正方形

  • 前两个看起来和预期的一样,但第三个完全是绿色的。

    TLDR:面具不应该是黑白的,这正是他们为了视觉效果而渲染的应该使用Src的地方,遮罩应该是不透明的,不应该使用Src的地方,遮罩应该是透明的。

    用下面的代码替换我的原始代码中的掩码生成,它会像预期的那样突然工作。(将黑色替换为透明,将白色替换为不透明):

    我花了整整一天半的时间把头撞在墙上,终于屈服了,第一次贴到了SO,然后当我停止思考的时候,我立刻解决了自己的问题,就像个白痴一样

    mask := image.NewNRGBA(bounds)
    draw.Draw(mask, bounds, image.NewUniform(color.Transparent), image.ZP, draw.Src)
    draw.Draw(mask, image.Rect(40, 40, 60, 60), image.NewUniform(color.Opaque), image.ZP, draw.Src)