更改像素值,保存并再次读取 returns 原始颜色

changing pixel value, saving and reading again returns the original color

我想将所有像素的蓝色值更改为 255,如果它等于 20。 我读取了源图像,draw.Draw 将其转换为新的 image.RGBA,以便我可以修改像素。

但是,当我获取输出图像(在执行程序后)并将其作为输入,并在 IF 块内放置一个调试点,并且 运行 程序处于调试模式时,我看到了多个点调试器停在那里。这意味着,我没有正确修改图像。

谁能告诉我,如何修改像素并正确保存?非常感谢

func changeOnePixelInImage() {
    imgPath := "./source.png"
    f, err := os.Open(imgPath)
    check(err)
    defer f.Close()
    sourceImage, _, err := image.Decode(f)

    size := sourceImage.Bounds().Size()
    destImage := image.NewRGBA(sourceImage.Bounds())
    draw.Draw(destImage, sourceImage.Bounds(), sourceImage, image.Point{}, draw.Over)

    for x := 0; x < size.X; x++ {
        for y := 0; y < size.Y; y++ {
            pixel := sourceImage.At(x, y)
            originalColor := color.RGBAModel.Convert(pixel).
            (color.RGBA)

            b := originalColor.B

            if b == 20 {
                b = 255 // <--- then i swap source and destination paths, and debug this line
            }

            c := color.RGBA{
                R: originalColor.R,
                G: originalColor.G,
                B: b,
                A: originalColor.A,
            }
            destImage.SetRGBA(x, y, c)
        }
    }
    ext := filepath.Ext(imgPath)
    newImagePath := fmt.Sprintf("%s/dest%s", filepath.Dir(imgPath), ext)
    fg, err := os.Create(newImagePath)
    check(err)
    defer fg.Close()
    err = jpeg.Encode(fg, destImage, &jpeg.Options{100})
    check(err)
}

我找到了问题的答案。 问题是,我正在解码 jpeg 图像,我发现 JPEG 图像质量下降(因此,像素值在此过程中被修改)来自这个 Whosebug 问题:Is JPEG lossless when quality is set to 100?

所以,我应该使用 PNG 图像。(即使我使用 source.png 作为源图像,它实际上是 jpg 图像 :/)

所以我将最后一行更改为:

if ext != ".png" {
    panic("cannot do my thing with jpg images, since they get compressed")
}
err = png.Encode(fg, destImage)