chai2010 / webp

WebP decoder and encoder for Go (Zero Dependencies).
http://godoc.org/github.com/chai2010/webp
BSD 3-Clause "New" or "Revised" License
522 stars 88 forks source link

RGBA vs NRGBA #20

Open jamesbikes opened 7 years ago

jamesbikes commented 7 years ago

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

chai2010 commented 7 years ago

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

And any PR are welcome.

Thanks for your feedback!

jamesbikes commented 7 years ago

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)
}
arisudesu commented 2 years ago

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