webp icon indicating copy to clipboard operation
webp copied to clipboard

RGBA vs NRGBA

Open jamesbikes opened this issue 9 years ago • 3 comments

The webp libraries return non-premultiplied alpha values. This library wraps those values in RGBA structs which represent premultiplied values.

Everywhere RGBA{} is created with data returned by the webp decoder, it should be NRGBA{}.

e.g. this fixes one of them: https://github.com/chai2010/webp/compare/master...jamesshoebox:nrgba?expand=1

Here's a (very) simple program that illustrates the problem. If you pass in a webp with alpha, you'll see that it doesn't blend correctly with the white background. https://gist.github.com/jamesshoebox/30ca5beada606842f98328481bf17f8d

jamesbikes avatar Nov 09 '16 15:11 jamesbikes

The gist is disabled in China. Can you paste the gist code?

And any PR are welcome.

Thanks for your feedback!

chai2010 avatar Nov 10 '16 01:11 chai2010

Sure! Sorry, a bit tight on time right now. May be able to make a PR later if you don't get to it first.

package main

import (
    "image"
    "image/color"
    "image/draw"
    "image/jpeg"
    _ "image/png"
    "log"
    "os"

    _ "github.com/chai2010/webp"
)

func main() {
    if len(os.Args) != 3 {
        log.Fatal("pass file")
    }

    in, _ := os.Open(os.Args[1])
    defer in.Close()

    img, _, _ := image.Decode(in)
    r := image.NewRGBA(img.Bounds())
    draw.Draw(r, img.Bounds(), &image.Uniform{color.White}, image.ZP, draw.Src)
    draw.Draw(r, img.Bounds(), img, image.ZP, draw.Over)
    out, _ := os.Create(os.Args[2])
    defer out.Close()
    jpeg.Encode(out, r, nil)
}

jamesbikes avatar Nov 10 '16 02:11 jamesbikes

Ran into this problem too. Decoded webp with alpha channel has damaged edges and colors. @chai2010 please can you look into?

A simple test to load webp and encode it to png fails:

import (
	"bytes"
	_ "embed"
	_ "github.com/chai2010/webp"
	"image"
	"image/png"
	"os"
)

//go:embed sticker.webp
var data []byte

func main() {
	img, _, err := image.Decode(bytes.NewReader(data))
	if err != nil {
		panic(err)
	}

	f, err := os.Create("out.png")
	if err != nil {
		panic(err)
	}
	defer f.Close()

	if err := png.Encode(f, img); err != nil {
		panic(err)
	}
}

Expected result is: sticker Actual: out

arisudesu avatar May 13 '22 15:05 arisudesu