I'm attempting to render barcodes in Go with user-input colours for both the data and background, and although the barcodes themselves are produced as expected in black and white, attempting to use them as a mask image in "image/draw"'s draw.DrawMask function results in full pass-through of the source image, ignoring the mask entirely.
This is very much counter to the examples given in the Go blog post on the image/draw package.
I've reduced the problem down to a fairly minimal example, a simple white square on a black background as a mask with uniform colours as source and destination, and the behaviour continues. I'm clearly failing to understand some element of how this function behaves, but attempts at finding similar problems others have encountered all seem to end with a different approach to the problem entirely (eg another library to do the job), rather than understanding the mistake in the usage of draw.DrawMask.
The code I've posted includes a function for writing the three output images to BMP files, but this behaviour is repeated if any other method of saving the image.Image data to a file is used.
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)
}
I would expect the code above to produce three images:
- A blue square, 100px by 100px
- A black square, 100px by 100px, with a 20px by 20px white square in its centre
- A blue square, 100px by 100px with a 20px by 20px green square in its centre
The first two appear as expected, but the third is entirely green.