Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

image/png: nearly black pixels under certain conditions with alpha channels #10191

Closed
nfnt opened this issue Mar 18, 2015 · 2 comments
Closed

image/png: nearly black pixels under certain conditions with alpha channels #10191

nfnt opened this issue Mar 18, 2015 · 2 comments
Assignees

Comments

@nfnt
Copy link

@nfnt nfnt commented Mar 18, 2015

I'm writing a small package for image resizing. While I've had my share of issues with images that have an alpha channel, this time I think that there may be an issue in the image/png package. I'm using Go 1.4.2 with OS X and under certain conditions there will be nearly black pixels in images created by png.Encode. The following code will produce an output that shows the problem:

package main

import (
    "bytes"
    "fmt"
    "image"
    "image/color"
    "image/png"
)

func main() {
    expected := image.NewRGBA64(image.Rect(0, 0, 7, 1))

    expected.SetRGBA64(0, 0, color.RGBA64{64561, 64547, 64541, 64566})
    expected.SetRGBA64(1, 0, color.RGBA64{65535, 65535, 65529, 65535})
    expected.SetRGBA64(2, 0, color.RGBA64{65118, 65535, 65535, 64688})
    expected.SetRGBA64(3, 0, color.RGBA64{42253, 29639, 24962, 46946})
    expected.SetRGBA64(4, 0, color.RGBA64{36967, 14176, 5958, 45390})
    expected.SetRGBA64(5, 0, color.RGBA64{38060, 17046, 9449, 45831})
    expected.SetRGBA64(6, 0, color.RGBA64{37852, 16504, 8790, 45746})

    var buffer bytes.Buffer
    png.Encode(&buffer, expected)

    actual, err := png.Decode(&buffer)
    if err != nil {
        panic(err)
    }

    for i := 0; i < 7; i++ {
        fmt.Printf("\n(%v,0):\n", i)
        fmt.Println(actual.At(i, 0).RGBA())
        fmt.Println(expected.At(i, 0).RGBA())
    }
}

While most color values of actual are about the same as in expected, pixel (2,0) of actual is very different from the one in expected and would show as nearly black in the output image. I didn't test if this is only happening with image.RGBA64 input.

@nigeltao
Copy link
Contributor

@nigeltao nigeltao commented Mar 18, 2015

It's a bug on this line:
expected.SetRGBA64(2, 0, color.RGBA64{65118, 65535, 65535, 64688})

Your R value is 65118 and your A value is 64688.

Go's color.RGBA64 type (and color.Color's RGBA method) is alpha-premultiplied, which means that the R, G and B values should all be <= the A value.

You probably want non-alpha-premultiplied instead: replace your "RGBA64"s with "NRGBA64"s.

@nigeltao nigeltao closed this Mar 18, 2015
@nfnt
Copy link
Author

@nfnt nfnt commented Mar 19, 2015

Thanks for the explanation and sorry for the inconvenience.

@golang golang locked and limited conversation to collaborators Jun 25, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.