使用golang的drawmask和draw.Over创建图像故障

huangapple go评论119阅读模式
英文:

Image glitch using golang's drawmask with draw.Over

问题

我正在使用golang重写一个最初用Python编写的脚本。我正在尝试重新创建的函数目前接受一张图片(一个彩色叠加层),并将其粘贴到一个相同大小的背景图(一张地图)上,透明度为50%。期望的输出如下所示,这是由我的Python脚本生成的:

使用golang的drawmask和draw.Over创建图像故障

我已经编写了以下的golang代码,试图用golang复制这个功能,参考了这个stackoverflow线程

在main.go中

// overlayImg是image.Image类型,包含彩色叠加层
overlayImg = lib.AddMap(overlayImg)
// lib.SaveToRecords是一个将image.Image overlayImg保存到指定路径(由字符串download.FileName指定)的函数
lib.SaveToRecords(overlayImg, download.FileName)

在myproject/lib包中

func AddMap(i image.Image) image.Image{
    // mapFile是背景地图图像
    mapFile, err := os.Open("./res/map.png")
    if err != nil { panic(err) }
    mapImg, _, err := image.Decode(mapFile)
    if err != nil { panic(err) }
    mask := image.NewUniform(color.Alpha{128})

    canvas := image.NewRGBA(mapImg.Bounds())
    draw.Draw(canvas, canvas.Bounds(), mapImg, image.Point{0, 0}, draw.Src)

    draw.DrawMask(canvas, canvas.Bounds(), i, image.Point{0, 0}, mask, image.Point{0, 0}, draw.Over)

    return canvas
}

然而,生成的图像在彩色叠加层的某些部分出现了一种“glitch”。这种颜色故障在每次运行脚本时都能可靠地重现,即使使用不同的叠加层(地图当然保持不变)。

使用golang的drawmask和draw.Over创建图像故障

我该如何消除这个“glitch”?


我尝试过的方法:

  • draw.DrawMask中使用draw.Draw,并将draw.Over作为“op”设置。结果是相同的颜色“glitch”,但没有透明度。

使用golang的drawmask和draw.Over创建图像故障

  • 使用draw.DrawMask,但将“op”设置为draw.Src。结果如下:

使用golang的drawmask和draw.Over创建图像故障

  • draw.Draw中使用draw.DrawMask,并将draw.Src作为“op”设置。这是使用稍微不同的叠加层图像进行的尝试。结果如下:

使用golang的drawmask和draw.Over创建图像故障


更新

根据putu的评论,我尝试将mask := image.NewUniform(color.Alpha{128})替换为mask := image.NewUniform(color.Alpha16{32767})。故障仍然存在。此外,这个故障并不像我想象的那样一致,只有大约10%的时间会出现。似乎这个故障出现取决于粘贴到背景上的图像的内容。

使用golang的drawmask和draw.Over创建图像故障


更新2

最初,mapImg的类型是image.NRGBA,icanvas的类型是image.RGBA。再次根据评论中的建议,我将mapImg转换为*image.RGBA以与其他部分匹配。为此,我使用了以下几行代码:

mapImg, _, err := image.Decode(mapFile)
mapImgRGBA := image.NewRGBA(mapImg.Bounds())
draw.Draw(mapImgRGBA, mapImgRGBA.Bounds(), mapImg, image.Point{0, 0}, draw.Src)
// 从这里开始使用mapImgRGBA替代mapImg

仍然无效:

使用golang的drawmask和draw.Over创建图像故障

英文:

I am rewriting with golang a script I originally wrote in python. The function I am trying to recreate currently takes one image (a coloured overlay) and pastes it on a background (a map) of the same size, with 50% transparency. The desired output, as produced by my python script, is:

使用golang的drawmask和draw.Over创建图像故障

The golang code I have written to try to replicate this in golang, with reference to this stackoverflow thread.

In main.go

// overlayImg is type image.Image, consists of the coloured overlay
overlayImg = lib.AddMap(overlayImg)
// lib.SaveToRecords is a function that saves image.Image overlayImg to path specified by string download.FileName
lib.SaveToRecords(overlayImg, download.FileName)

In package myproject/lib

func AddMap(i image.Image) image.Image{
    // mapFile is the background map image
    mapFile, err := os.Open("./res/map.png")
    if err != nil { panic(err) }
    mapImg, _, err := image.Decode(mapFile)
    if err != nil { panic(err) }
    mask := image.NewUniform(color.Alpha{128})

    canvas := image.NewRGBA(mapImg.Bounds())
    draw.Draw(canvas, canvas.Bounds(), mapImg, image.Point{0, 0}, draw.Src)

    draw.DrawMask(canvas, canvas.Bounds(), i, image.Point{0, 0}, mask, image.Point{0, 0}, draw.Over)

    return canvas
}

However, the resulting image is produced with a sort of 'glitch' in parts of the coloured overlay. This colour glitch is reliably reproduced on each run of the script, even with different overlays (the map stays the same throughout, of course).

使用golang的drawmask和draw.Over创建图像故障

How do I get rid of the 'glitch'?


Things I have tried:

  • Using draw.Draw in place of draw.DrawMask with draw.Over as the 'op' setting. Results in same colour 'glitch', but without transparency.

使用golang的drawmask和draw.Over创建图像故障

  • Using draw.DrawMask, except with draw.Src as the 'op' setting. Result:

使用golang的drawmask和draw.Over创建图像故障

  • Using draw.Draw in place of draw.DrawMask, and with draw.Src as the 'op' setting. This was with a slightly different overlay image. Result:

使用golang的drawmask和draw.Over创建图像故障


Update

I've tried assigning mask := image.NewUniform(color.Alpha16{32767}) in place of mask := image.NewUniform(color.Alpha{128}) according to putu's comment. Glitch still appears. Additionally, this glitch is not as consistent as I thought, showing up at only roughly 10% of the time. It seems the glitch shows up depending on the content of the image pasted unto the background.

使用golang的drawmask和draw.Over创建图像故障


Update 2

Originally, mapImg was of type *image.NRGBA, i and canvas of type *image.RGBA. Once again following the advice in the comments, I converted mapImg to type *image.RGBA to match with the rest. To do this, I used the following few lines of code:

mapImg, _, err := image.Decode(mapFile)
mapImgRGBA := image.NewRGBA(mapImg.Bounds())
draw.Draw(mapImgRGBA, mapImgRGBA.Bounds(), mapImg, image.Point{0, 0}, draw.Src)
// Use mapImgRGBA in place of mapImg from here

Still don't work:

使用golang的drawmask和draw.Over创建图像故障

答案1

得分: 2

感谢您在freenode的#go-nuts频道中使用noethics请求查看原始叠加图层,我在处理每一行操作图像后生成输出时发现了问题。

问题不在于“image/draw”,而是在于我使用的一个外部库来调整叠加图层的尺寸,即“github.com/nfnt/resize”。

调整大小之前的叠加图层:

使用golang的drawmask和draw.Over创建图像故障

调整大小后的叠加图层(红色和黑色像素不理想):

使用golang的drawmask和draw.Over创建图像故障


更新

问题甚至不是由于“github.com/nfnt/resize”。我只是使用了错误的插值算法。事实证明,双线性插值对我正在处理的图像给出了最佳输出。我怀疑这也是我用来编写原始脚本的库中使用的插值算法。

使用golang的drawmask和draw.Over创建图像故障

英文:

Thanks to use noethics in the freenode #go-nuts channel for requesting a look at the original overlay, I found the issue while generating the output after each line that manipulates the image.

The issue is not with "image/draw", but with an external library I'm using to resize the overlay to the dimensions of the map, "github.com/nfnt/resize".

The overlay before resizing:

使用golang的drawmask和draw.Over创建图像故障

The overlay after resizing (red & black pixels undesirable):

使用golang的drawmask和draw.Over创建图像故障


Update

It's not even an issue with "github.com/nfnt/resize". I was simply using the wrong interpolation algorithm. Turns out bilinear gives me the best output for the image I am working with. I suspect it's also the one used in the library I used to write my original script in.

使用golang的drawmask和draw.Over创建图像故障

huangapple
  • 本文由 发表于 2017年5月14日 10:39:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/43959864.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定