Changing image color - semi-transparent pixels completely different

Viewed 179

I am trying to develop a Go function that will replace pixels of a specified color in a PNG image with a different color, but also change the color of the semi-transparent pixels.

Original image: Text

Resulting image: Text

Resulting image zoomed in: Text

As it can be seen when comparing, fully gray pixels were successfully colored, but semi-transparent ones turned kind of blue/green instead of transparent pink. I am not sure what I am doing wrong. Below is my code snippet with comments.

    img, name, format, width, height, err := FromURLGet(request.URL) // fetches image data from the URL, img is an image.Image object
    if err != nil {
        return res, errors.New("Error: could not fetch image")
    }

    upLeft := image.Point{0, 0}
    lowRight := image.Point{width, height}
    newImg := image.NewRGBA(image.Rectangle{upLeft, lowRight}) // creates a new image of same size for drawing

    selectedColor, err := ParseHexColorFast(request.Hex) // retrieves color.RGBA based on provided hex
    if err != nil {
        return res, err
    }

    // loop through existing pixels
    for y := 0; y < height; y++ {
        for x := 0; x < width; x++ {
            // get current pixel color and convert it to uint8
            r, g, b, a := img.At(x, y).RGBA()
            r2 := uint8(r >> 8)
            g2 := uint8(g >> 8)
            b2 := uint8(b >> 8)
            a2 := uint8(a >> 8)

            // if pixel is the non-transparent gray color, replace it with selected
            if r2 == 189 && g2 == 188 && b2 == 188 && a2 == 255 {
                newImg.Set(x, y, selectedColor)
            } else if r2 == 0 && g2 == 0 && b2 == 0 && a2 == 1 {
                // if pixel is fully transparent,  keep it the same
                newImg.Set(x, y, color.RGBA{r2, g2, b2, a2})
            } else {
                // else if pixel is a different color or semi-transparent, set it to required color but keep transparency a2

                fmt.Println("current RGBA", r2, g2, b2, a2)
                fmt.Println("setting RGBA for X, Y", x, y, selectedColor.R, selectedColor.G, selectedColor.B, a2)

                newImg.Set(x, y, color.RGBA{selectedColor.R, selectedColor.G, selectedColor.B, a2})
            }
        }
    }

buf := new(bytes.Buffer)
err = png.Encode(buf, newImg)

Am I correctly setting the Alpha channel? Since the colors from the prints I have appear as supposed to.

For example: current RGBA 118 117 117 159 selected color RGBA 214 30 110 255 setting RGBA for X, Y 31 29 214 30 110 159

0 Answers
Related