为什么Go的draw.DrawMask似乎忽略了我的黑白蒙版?

时间:2019-04-27 11:47:49

标签: go draw

我正在尝试使用用户输入的颜色在Go语言中渲染条形码,以用于数据和背景,尽管条形码本身是按预期的黑白方式生成的,但仍尝试将其用作“ image /绘制”的draw.DrawMask函数导致源图像的完全通过,而完全忽略了蒙版。

这与Go blog post on the image/draw package中给出的示例完全相反。

我已将问题简化为一个最小的示例,即黑色背景上的简单白色正方形作为蒙版,并使用统一的颜色作为源和目标,并且行为继续。我显然无法理解此函数的行为方式,但是试图发现其他人遇到的类似问题的尝试似乎以完全解决问题的另一种方法(例如,另一个可以完成此工作的库)结束,而不是理解使用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)
}

我希望上面的代码会产生三个图像:

  1. 一个蓝色正方形,100像素x 100像素
  2. 黑色正方形,其中心为100px x 100px,白色正方形为20px x 20px
  3. 中心为100px x 100px的蓝色正方形,中间为20px x 20px的绿色正方形

前两个出现预期,但第三个完全绿色。

1 个答案:

答案 0 :(得分:0)

TLDR:蒙版不应该是黑白的,这只是它们渲染视觉效果的方式。 在应该使用Src的情况下,蒙版应该是不透明的;在不应该使用Src的情况下,蒙版应该是透明的。

使用以下代码在我的原始代码中替换蒙版生成,所有这些突然都能按预期工作。 (将黑色替换为透明,将白色替换为不透明):

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)

我花了整整一天半的时间将头撞在墙上,终于屈服了,并第一次贴在SO上,然后我一想到白痴就立刻解决了自己的问题。 / p>