Почему Draw в Go.DrawMask игнорирует мою черно-белую маску? - PullRequest
0 голосов
/ 27 апреля 2019

Я пытаюсь визуализировать штрих-коды в Go с использованием цветов, вводимых пользователем как для данных, так и для фона, и хотя сами штрих-коды создаются, как и ожидалось, в черно-белом режиме, я пытаюсь использовать их в качестве маскирующего изображения в "image / Функция draw ". draw.DrawMask приводит к полному переносу исходного изображения, полностью игнорируя маску.

Это очень сильно противоречит примерам, приведенным в блоге Go на упаковке image / draw .

Я сократил проблему до довольно минимального примера, простого белого квадрата на черном фоне в виде маски с однородными цветами в качестве источника и места назначения, и поведение продолжается. Я явно не понимаю некоторый элемент поведения этой функции, но попытки найти похожие проблемы, с которыми сталкивались другие, похоже, заканчиваются совершенно другим подходом к проблеме (например, другой библиотекой, выполняющей работу), а не пониманием ошибка в использовании 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 на 100 пикселей
  2. Черный квадрат, 100 на 100 пикселей, с белым квадратом 20 на 20 пикселей в его центре
  3. Синий квадрат, 100 на 100 пикселей, с зеленым квадратом 20 на 20 пикселей в его центре

Первые два появляются, как и ожидалось, но третий полностью зеленый.

1 Ответ

0 голосов
/ 27 апреля 2019

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, затем сразурешил свою собственную проблему, как только я перестал думать об этом, как идиот.

...