Documentation
¶
Overview ¶
Package webp implements a decoder and encoder for WEBP images.
WEBP is defined at: https://developers.google.com/speed/webp/docs/riff_container
Install ¶
Install `GCC` or `MinGW` (http://tdm-gcc.tdragon.net/download) at first, and then run these commands:
- `go get github.com/chai2010/webp`
- `go run hello.go`
Examples ¶
This is a simple example:
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"github.com/chai2010/webp"
)
func main() {
var buf bytes.Buffer
var width, height int
var data []byte
var err error
// Load file data
if data, err = ioutil.ReadFile("./testdata/1_webp_ll.webp"); err != nil {
log.Fatal(err)
}
// GetInfo
if width, height, _, err = webp.GetInfo(data); err != nil {
log.Fatal(err)
}
fmt.Printf("width = %d, height = %d\n", width, height)
// GetMetadata
if metadata, err := webp.GetMetadata(data, "ICCP"); err != nil {
fmt.Printf("Metadata: err = %v\n", err)
} else {
fmt.Printf("Metadata: %s\n", string(metadata))
}
// Decode webp
m, err := webp.Decode(bytes.NewReader(data))
if err != nil {
log.Fatal(err)
}
// Encode lossless webp
if err = webp.Encode(&buf, m, &webp.Options{Lossless: true}); err != nil {
log.Fatal(err)
}
if err = ioutil.WriteFile("output.webp", buf.Bytes(), 0666); err != nil {
log.Fatal(err)
}
fmt.Printf("Save output.webp ok\n")
}
Decode and Encode as RGB format:
m, err := webp.DecodeRGB(data)
if err != nil {
log.Fatal(err)
}
data, err := webp.EncodeRGB(m)
if err != nil {
log.Fatal(err)
}
BUGS ¶
Report bugs to <[email protected]>.
Thanks!
Index ¶
- Constants
- func ChannelsOf(m image.Image) int
- func ColorModel(channels int, dataType reflect.Kind) color.Model
- func Decode(r io.Reader) (m image.Image, err error)
- func DecodeConfig(r io.Reader) (config image.Config, err error)
- func DecodeGray(data []byte) (m *image.Gray, err error)
- func DecodeRGBA(data []byte) (m *image.RGBA, err error)
- func DecodeRGBEx(data []byte, cbuf CBuffer) (m *RGBImage, pix CBuffer, err error)
- func DepthOf(m image.Image) int
- func Encode(w io.Writer, m image.Image, opt *Options) (err error)
- func EncodeGray(m image.Image, quality float32) (data []byte, err error)
- func EncodeLosslessGray(m image.Image) (data []byte, err error)
- func EncodeLosslessRGB(m image.Image) (data []byte, err error)
- func EncodeLosslessRGBA(m image.Image) (data []byte, err error)
- func EncodeRGB(m image.Image, quality float32) (data []byte, err error)
- func EncodeRGBA(m image.Image, quality float32) (data []byte, err error)
- func GetInfo(data []byte) (width, height int, hasAlpha bool, err error)
- func GetInfoEx(data []byte, cbuf CBuffer) (width, height int, hasAlpha bool, err error)
- func GetMetadata(data []byte, format string) (metadata []byte, err error)
- func Load(name string, cbuf ...CBuffer) (m image.Image, err error)
- func LoadConfig(name string, cbuf ...CBuffer) (config image.Config, err error)
- func Save(name string, m image.Image, opt *Options, cbuf ...CBuffer) (err error)
- func SetMetadata(data, metadata []byte, format string) (newData []byte, err error)
- func SizeofImage(m image.Image) int
- func SizeofKind(dataType reflect.Kind) int
- func SizeofPixel(channels int, dataType reflect.Kind) int
- type CBuffer
- func DecodeGrayEx(data []byte, cbuf CBuffer) (m *image.Gray, pix CBuffer, err error)
- func DecodeRGBAEx(data []byte, cbuf CBuffer) (m *image.RGBA, pix CBuffer, err error)
- func EncodeGrayEx(m image.Image, quality float32, cbuf CBuffer) (data CBuffer, err error)
- func EncodeLosslessGrayEx(m image.Image, cbuf CBuffer) (data CBuffer, err error)
- func EncodeLosslessRGBAEx(m image.Image, cbuf CBuffer) (data CBuffer, err error)
- func EncodeLosslessRGBEx(m image.Image, cbuf CBuffer) (data CBuffer, err error)
- func EncodeRGBAEx(m image.Image, quality float32, cbuf CBuffer) (data CBuffer, err error)
- func EncodeRGBEx(m image.Image, quality float32, cbuf CBuffer) (data CBuffer, err error)
- func NewCBuffer(size int, dontResize ...bool) CBuffer
- type MemP
- type MemPColor
- type MemPImage
- func (p *MemPImage) AsStdImage() (m image.Image, ok bool)
- func (p *MemPImage) At(x, y int) color.Color
- func (p *MemPImage) Bounds() image.Rectangle
- func (p *MemPImage) Channels() int
- func (p *MemPImage) Clone() *MemPImage
- func (p *MemPImage) ColorModel() color.Model
- func (p *MemPImage) DataType() reflect.Kind
- func (p *MemPImage) MemPMagic() string
- func (p *MemPImage) Pix() []byte
- func (p *MemPImage) PixOffset(x, y int) int
- func (p *MemPImage) PixelAt(x, y int) []byte
- func (p *MemPImage) Set(x, y int, c color.Color)
- func (p *MemPImage) SetPixel(x, y int, c []byte)
- func (p *MemPImage) StdImage() image.Image
- func (p *MemPImage) Stride() int
- func (p *MemPImage) SubImage(r image.Rectangle) image.Image
- type Options
- type PixSilce
- func (d PixSilce) Bytes() (v []byte)
- func (d PixSilce) Complex128s() (v []complex128)
- func (d PixSilce) Complex64s() (v []complex64)
- func (d PixSilce) Float32s() (v []float32)
- func (d PixSilce) Float64s() (v []float64)
- func (d PixSilce) Int16s() (v []int16)
- func (d PixSilce) Int32s() (v []int32)
- func (d PixSilce) Int64s() (v []int64)
- func (d PixSilce) Int8s() (v []int8)
- func (d PixSilce) SetValue(i int, dataType reflect.Kind, v float64)
- func (d PixSilce) Slice(newSliceType reflect.Type) interface{}
- func (d PixSilce) SwapEndian(dataType reflect.Kind)
- func (d PixSilce) Uint16s() (v []uint16)
- func (d PixSilce) Uint32s() (v []uint32)
- func (d PixSilce) Uint64s() (v []uint64)
- func (d PixSilce) Uint8s() []uint8
- func (d PixSilce) Value(i int, dataType reflect.Kind) float64
- type RGB48Image
- func (p *RGB48Image) At(x, y int) color.Color
- func (p *RGB48Image) Bounds() image.Rectangle
- func (p *RGB48Image) Channels() int
- func (p *RGB48Image) ColorModel() color.Model
- func (p *RGB48Image) DataType() reflect.Kind
- func (p *RGB48Image) MemPMagic() string
- func (p *RGB48Image) Opaque() bool
- func (p *RGB48Image) Pix() []byte
- func (p *RGB48Image) PixOffset(x, y int) int
- func (p *RGB48Image) RGB48At(x, y int) [3]uint16
- func (p *RGB48Image) Set(x, y int, c color.Color)
- func (p *RGB48Image) SetRGB48(x, y int, c [3]uint16)
- func (p *RGB48Image) Stride() int
- func (p *RGB48Image) SubImage(r image.Rectangle) image.Image
- type RGBImage
- func (p *RGBImage) At(x, y int) color.Color
- func (p *RGBImage) Bounds() image.Rectangle
- func (p *RGBImage) Channels() int
- func (p *RGBImage) ColorModel() color.Model
- func (p *RGBImage) DataType() reflect.Kind
- func (p *RGBImage) MemPMagic() string
- func (p *RGBImage) Opaque() bool
- func (p *RGBImage) Pix() []byte
- func (p *RGBImage) PixOffset(x, y int) int
- func (p *RGBImage) RGBAt(x, y int) [3]uint8
- func (p *RGBImage) Set(x, y int, c color.Color)
- func (p *RGBImage) SetRGB(x, y int, c [3]uint8)
- func (p *RGBImage) Stride() int
- func (p *RGBImage) SubImage(r image.Rectangle) image.Image
- type SizeofImager
Examples ¶
Constants ¶
const DefaulQuality = 90
const (
MemPMagic = "MemP" // See https://github.com/chai2010/image
)
Variables ¶
This section is empty.
Functions ¶
func ChannelsOf ¶
func ColorModel ¶
Example ¶
rgba := color.RGBA{R: 101, G: 102, B: 103, A: 104}
c := ColorModel(4, reflect.Uint8).Convert(rgba).(MemPColor)
fmt.Printf("c = %v\n", c)
Output: c = {4 uint8 [101 102 103 104]}
func DecodeConfig ¶
DecodeConfig returns the color model and dimensions of a WEBP image without decoding the entire image.
func DecodeRGBEx ¶
func Encode ¶
Encode writes the image m to w in WEBP format.
Example ¶
m, err := Load("./testdata/1_webp_ll.webp")
if err != nil {
log.Fatal(err)
}
var buf bytes.Buffer
if err := Encode(&buf, m, nil); err != nil {
log.Fatal(err)
}
_ = buf.Bytes()
Example (Lossless) ¶
m, err := Load("./testdata/1_webp_ll.webp")
if err != nil {
log.Fatal(err)
}
var buf bytes.Buffer
if err := Encode(&buf, m, &Options{Lossless: true}); err != nil {
log.Fatal(err)
}
_ = buf.Bytes()
Example (Rgb) ¶
rgb := NewRGBImage(image.Rect(0, 0, 400, 300))
var buf bytes.Buffer
if err := Encode(&buf, rgb, nil); err != nil {
log.Fatal(err)
}
_ = buf.Bytes()
Example (Rgb48MemP) ¶
rgb48 := NewMemPImage(image.Rect(0, 0, 400, 300), 3, reflect.Uint16)
var buf bytes.Buffer
if err := Encode(&buf, rgb48, nil); err != nil {
log.Fatal(err)
}
_ = buf.Bytes()
func GetInfo ¶
Example ¶
data := xLoadData("1_webp_a.webp")
width, height, hasAlpha, err := GetInfo(data)
if err != nil {
log.Fatal(err)
}
fmt.Printf("width: %v\n", width)
fmt.Printf("height: %v\n", height)
fmt.Printf("hasAlpha: %v\n", hasAlpha)
Output: width: 400 height: 301 hasAlpha: true
Example (NoAlpha) ¶
data := xLoadData("video-001.webp")
width, height, hasAlpha, err := GetInfo(data)
if err != nil {
log.Fatal(err)
}
fmt.Printf("width: %v\n", width)
fmt.Printf("height: %v\n", height)
fmt.Printf("hasAlpha: %v\n", hasAlpha)
Output: width: 150 height: 103 hasAlpha: false
func GetInfoEx ¶
Example ¶
cbuf := xLoadCBuffer("1_webp_a.webp")
defer cbuf.Close()
width, height, hasAlpha, err := GetInfoEx(cbuf.CData(), cbuf)
if err != nil {
log.Fatal(err)
}
fmt.Printf("width: %v\n", width)
fmt.Printf("height: %v\n", height)
fmt.Printf("hasAlpha: %v\n", hasAlpha)
Output: width: 400 height: 301 hasAlpha: true
func GetMetadata ¶
GetMetadata return EXIF/ICCP/XMP format metadata.
func Load ¶
Example ¶
m, err := Load("./testdata/1_webp_ll.webp")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Bounds = %v\n", m.Bounds())
Output: Bounds = (0,0)-(400,301)
Example (Cbuf) ¶
cbuf := NewCBuffer(8 << 20) // 8MB
defer cbuf.Close()
m, err := Load("./testdata/1_webp_ll.webp", cbuf)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Bounds = %v\n", m.Bounds())
Output: Bounds = (0,0)-(400,301)
func LoadConfig ¶
Example ¶
cfg, err := LoadConfig("./testdata/1_webp_ll.webp")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Width = %d\n", cfg.Width)
fmt.Printf("Height = %d\n", cfg.Height)
Output: Width = 400 Height = 301
Example (Cbuf) ¶
cbuf := NewCBuffer(0)
defer cbuf.Close()
cfg, err := LoadConfig("./testdata/1_webp_ll.webp", cbuf)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Width = %d\n", cfg.Width)
fmt.Printf("Height = %d\n", cfg.Height)
Output: Width = 400 Height = 301
func Save ¶
Example ¶
tmpname := "z_test_ExampleSave.webp"
defer os.Remove(tmpname)
gray := NewMemPImage(image.Rect(0, 0, 400, 300), 1, reflect.Uint8)
if err := Save(tmpname, gray, &Options{Quality: 75}); err != nil {
log.Fatal(err)
}
Example (Cbuf) ¶
tmpname := "z_test_ExampleSave.webp"
defer os.Remove(tmpname)
b := image.Rect(0, 0, 400, 300)
cbuf := NewCBuffer(b.Dx() * b.Dy() * 4)
defer cbuf.Close()
rgba := &image.RGBA{
Pix: cbuf.CData(),
Stride: b.Dx() * 4,
Rect: b,
}
if err := Save(tmpname, rgba, nil, cbuf); err != nil {
log.Fatal(err)
}
gray := &image.Gray{
Pix: cbuf.CData(),
Stride: b.Dx() * 1,
Rect: b,
}
if err := Save(tmpname, gray, nil, cbuf); err != nil {
log.Fatal(err)
}
func SetMetadata ¶
SetMetadata set EXIF/ICCP/XMP format metadata.
func SizeofImage ¶
func SizeofKind ¶
Example ¶
fmt.Printf("%v = %v\n", reflect.Uint8, SizeofKind(reflect.Uint8))
fmt.Printf("%v = %v\n", reflect.Uint16, SizeofKind(reflect.Uint16))
fmt.Printf("%v = %v\n", reflect.Uint32, SizeofKind(reflect.Uint32))
fmt.Printf("%v = %v\n", reflect.Float32, SizeofKind(reflect.Float32))
fmt.Printf("%v = %v\n", reflect.Float64, SizeofKind(reflect.Float64))
Output: uint8 = 1 uint16 = 2 uint32 = 4 float32 = 4 float64 = 8
func SizeofPixel ¶
Example ¶
fmt.Printf("sizeof(gray) = %d\n", SizeofPixel(1, reflect.Uint8))
fmt.Printf("sizeof(gray16) = %d\n", SizeofPixel(1, reflect.Uint16))
fmt.Printf("sizeof(rgb) = %d\n", SizeofPixel(3, reflect.Uint8))
fmt.Printf("sizeof(rgb48) = %d\n", SizeofPixel(3, reflect.Uint16))
fmt.Printf("sizeof(rgba) = %d\n", SizeofPixel(4, reflect.Uint8))
fmt.Printf("sizeof(rgba64) = %d\n", SizeofPixel(4, reflect.Uint16))
fmt.Printf("sizeof(float32) = %d\n", SizeofPixel(1, reflect.Float32))
Output: sizeof(gray) = 1 sizeof(gray16) = 2 sizeof(rgb) = 3 sizeof(rgb48) = 6 sizeof(rgba) = 4 sizeof(rgba64) = 8 sizeof(float32) = 4
Types ¶
type CBuffer ¶
type CBuffer interface {
CBufMagic() string
CanResize() bool
Resize(size int) error
CData() []byte
Own(d []byte) bool
io.Closer
}
Example ¶
cbuf := NewCBuffer(100)
defer cbuf.Close()
data := cbuf.CData()
fmt.Printf("CBufMagic: %v\n", cbuf.CBufMagic())
fmt.Printf("cbuf own data[:]: %v\n", cbuf.Own(data[:]))
fmt.Printf("cbuf own data[10:]: %v\n", cbuf.Own(data[10:]))
fmt.Printf("cbuf own []byte{1}: %v\n", cbuf.Own([]byte{1}))
Output: CBufMagic: CBufMagic cbuf own data[:]: true cbuf own data[10:]: true cbuf own []byte{1}: false
Example (LockAddress) ¶
const dontResize = true
cbuf := NewCBuffer(100, dontResize)
defer cbuf.Close()
fmt.Printf("CanResize: %v\n", cbuf.CanResize())
// can't resize now
if err := cbuf.Resize(len(cbuf.CData()) * 2); err == nil {
log.Fatal("expect not nil")
}
// size is still 100
data := cbuf.CData()
fmt.Printf("len(data): %d\n", len(data))
Output: CanResize: false len(data): 100
Example (Resize) ¶
cbuf := NewCBuffer(100)
defer cbuf.Close()
data := cbuf.CData()
fmt.Printf("len(data): %d\n", len(data))
// resize, the old data is invalid!!!
if err := cbuf.Resize(len(data) * 2); err != nil {
log.Fatal(err)
}
// now size is 200
data = cbuf.CData()
fmt.Printf("len(data): %d\n", len(data))
Output: len(data): 100 len(data): 200
func DecodeGrayEx ¶
func DecodeRGBAEx ¶
func EncodeGrayEx ¶
func EncodeLosslessGrayEx ¶
func EncodeLosslessRGBAEx ¶
func EncodeLosslessRGBEx ¶
func EncodeRGBAEx ¶
func EncodeRGBEx ¶
func NewCBuffer ¶
type MemP ¶
type MemP interface {
MemPMagic() string
Bounds() image.Rectangle
Channels() int
DataType() reflect.Kind
Pix() []byte // PixSilce type
// Stride is the Pix stride (in bytes, must align with SizeofKind(p.DataType))
// between vertically adjacent pixels.
Stride() int
}
MemP Image Spec (Native Endian), see https://github.com/chai2010/image.
type MemPImage ¶
type MemPImage struct {
XMemPMagic string // MemP
XRect image.Rectangle
XChannels int
XDataType reflect.Kind
XPix PixSilce
XStride int
}
func NewMemPImage ¶
func NewMemPImageFrom ¶
func (*MemPImage) ColorModel ¶
type PixSilce ¶
type PixSilce []byte
Example ¶
a := []int32{101, 102, 103}
b := AsPixSilce(a)
b.Int32s()[0] = 12345
b.SetValue(1, reflect.Int32, 1002)
b.SetValue(2, reflect.Int32, 1003.5)
fmt.Printf("len(b) = %d\n", len(b))
fmt.Printf("b.Int32s() = %v\n", b.Int32s())
Output: len(b) = 12 b.Int32s() = [12345 1002 1003]
func AsPixSilce ¶
func AsPixSilce(slice interface{}) (d PixSilce)
AsPixSilce convert a normal slice to byte slice.
Convert []X to []byte:
x := make([]X, xLen) y := AsPixSilce(x)
func (PixSilce) Complex128s ¶
func (d PixSilce) Complex128s() (v []complex128)
func (PixSilce) Complex64s ¶
func (PixSilce) Slice ¶
Slice convert a normal slice to new type slice.
Convert []byte to []Y:
x := make([]byte, xLen) y := PixSilce(x).Slice(reflect.TypeOf([]Y(nil))).([]Y)
func (PixSilce) SwapEndian ¶
Example ¶
rgba64 := image.NewRGBA64(image.Rect(0, 0, 1, 1))
rgba64.SetRGBA64(0, 0, color.RGBA64{
R: 0x0102,
G: 0x0304,
B: 0x0506,
A: 0x0708,
})
// pix is big-endian format
fmt.Printf("big-endian: %v\n", rgba64.Pix)
AsPixSilce(rgba64.Pix).SwapEndian(reflect.Uint16)
fmt.Printf("little-endian: %v\n", rgba64.Pix)
Output: big-endian: [1 2 3 4 5 6 7 8] little-endian: [2 1 4 3 6 5 8 7]
type RGB48Image ¶
type RGB48Image struct {
XPix []uint8 // XPix use Native Endian (same as MemP) !!!
XStride int
XRect image.Rectangle
}
func NewRGB48Image ¶
func NewRGB48Image(r image.Rectangle) *RGB48Image
NewRGB48Image returns a new RGB48Image with the given bounds.
func NewRGB48ImageFrom ¶
func NewRGB48ImageFrom(m image.Image) *RGB48Image
func (*RGB48Image) Bounds ¶
func (p *RGB48Image) Bounds() image.Rectangle
func (*RGB48Image) Channels ¶
func (p *RGB48Image) Channels() int
func (*RGB48Image) ColorModel ¶
func (p *RGB48Image) ColorModel() color.Model
func (*RGB48Image) DataType ¶
func (p *RGB48Image) DataType() reflect.Kind
func (*RGB48Image) MemPMagic ¶
func (p *RGB48Image) MemPMagic() string
func (*RGB48Image) Opaque ¶
func (p *RGB48Image) Opaque() bool
Opaque scans the entire image and reports whether it is fully opaque.
func (*RGB48Image) Pix ¶
func (p *RGB48Image) Pix() []byte
func (*RGB48Image) PixOffset ¶
func (p *RGB48Image) PixOffset(x, y int) int
PixOffset returns the index of the first element of XPix that corresponds to the pixel at (x, y).
func (*RGB48Image) RGB48At ¶
func (p *RGB48Image) RGB48At(x, y int) [3]uint16
func (*RGB48Image) SetRGB48 ¶
func (p *RGB48Image) SetRGB48(x, y int, c [3]uint16)
func (*RGB48Image) Stride ¶
func (p *RGB48Image) Stride() int
type RGBImage ¶
func NewRGBImage ¶
NewRGBImage returns a new RGBImage with the given bounds.
func NewRGBImageFrom ¶
func (*RGBImage) ColorModel ¶
type SizeofImager ¶
type SizeofImager interface {
SizeofImage() int
}
