2017-05-14 9 views
0

我用golang改写了一个我最初在python中编写的脚本。我试图重新创建的函数当前需要一个图像(一个彩色覆盖图)并将其粘贴到相同大小的背景(地图)上,透明度为50%。所需的输出,如我的python脚本制作,是:图像故障使用golang的drawmask与draw.Over

Desired Output with Python

我写的就是尽力golang复制此,参照this stackoverflow thread的golang代码。

在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) 

在包的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 
} 

然而,产生与在着色的部分排序 '毛刺' 的结果的图像覆盖。这种颜色故障可以在脚本的每次运行中可靠地重现,即使使用不同的叠加层(当然,地图始终保持相同)。

Output with Golang

如何摆脱 '毛刺' 的?


事情我已经尝试:

  • 代替draw.DrawMask使用draw.Drawdraw.Over的 '运' 的设置。导致相同颜色'毛刺',但没有透明度。

draw.Draw with draw.Over

  • 使用draw.DrawMask,除了与draw.Src为 'OP' 的设置。结果:

draw.DrawMask with draw.Src

  • 使用draw.Draw代替draw.DrawMask,并与draw.Src为 '运' 的设置。这是与一个稍微不同的覆盖图像。结果:

draw.Draw with draw.Src


更新

我试图根据putu's comment代替mask := image.NewUniform(color.Alpha{128})分配mask := image.NewUniform(color.Alpha16{32767})。故障仍然出现。此外,这个小故障并不像我想象的那样一致,只在大约10%的时间出现。这似乎是毛刺显示取决于图像的内容粘贴到背景

drawMask with draw.Over and Alpha16


更新2

本来mapImg是类型* image.NRGBA,i和类型* image.RGBA的canvas。再次遵循in the comments的建议,我将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) 
// Use mapImgRGBA in place of mapImg from here 

仍然不工作:

Converting mapImg to RGBA

+1

如何,如果你改变了'color.Alpha {128}''到{color.Alpha16 32767}'? – putu

+0

@putu嗨,谢谢你的建议!我必须再次向你确认它是否有效,因为现在'color.Alpha {128}'和'color.Alpha16 {32767}'都给了我想要的东西。似乎这里的小故障比我想象的更难以重现......如果我能够再次发生故障,我会更新你。 – ning

+1

当您要粘贴到背景的图像与遮罩具有不同的“bpp”时,可能会出现毛刺,例如, 16位与8位(color.Alpha),8位与16位(color.Alpha16)等。现在让我们使用'color.Alpha'作为掩码。打印要粘贴到背景上的图像类型(“AddImage”中的“i”),并观察毛刺发生时的图像类型。另外,您可能还需要打印解码图像的类型(即地图)。 – putu

回答

1

感谢在freenode的#去螺母通道使用noethics用于请求看看原来的覆盖,我发现这个问题,同时在每一行处理图像后生成输出。

问题不在于“图像/绘制”,而在于使用外部库来调整覆盖图的大小以适应地图的尺寸​​“github.com/nfnt/resize”。

之前叠加调整大小:

Original image

叠加调整大小(红色&黑色像素不期望的)后:

return resize.Resize(1491, 836, i, resize.Lanczos3)


更新

这甚至不是“github.com/nfnt/resize”的问题。我只是使用错误的插值算法。原来的双线性给了我正在使用的图像的最佳输出。我怀疑它也是我用来写我原来的脚本库使用的一个。

interpolationComparison