我正在尝试使用用户输入颜色为数据和背景渲染Go中的条形码,尽管条形码本身按预期以黑白生成,但尝试将它们用作“图像/绘图”中的蒙版图像s 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)
}
我希望上面的代码可以生成三个图像:
前两个出现了预期,但第三个完全是绿色。
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,然后我一想到它就立刻解决了我自己的问题,就像一个白痴。