go-libwebp

Experimental translation from libwebp to Go source.
Log | Files | Refs | README | LICENSE

encode.go (1919B)


      1 package webp
      2 
      3 import (
      4 	"image"
      5 	"io"
      6 )
      7 
      8 // Encode an image into webp with default settings.
      9 func Encode(w io.Writer, m image.Image, opt ...EncodeOption) error {
     10 	var enc Encoder
     11 	for _, op := range opt {
     12 		op(&enc)
     13 	}
     14 	if enc.Quality <= 0.0 {
     15 		enc.Quality = 0.9
     16 	}
     17 	if enc.Quality > 1.0 {
     18 		enc.Quality = 1.0
     19 	}
     20 	if enc.Lossless {
     21 		enc.Quality = 1.0
     22 	}
     23 	return enc.Encode(w, m)
     24 }
     25 
     26 // EncodeOption configures the encoder.
     27 type EncodeOption func(*Encoder)
     28 
     29 // Quality in the range (0,1].
     30 // Quality of 1 implies Lossless.
     31 func Quality(q float32) EncodeOption {
     32 	return func(enc *Encoder) {
     33 		enc.Quality = q
     34 	}
     35 }
     36 
     37 // Lossless will ignore quality.
     38 func Lossless() EncodeOption {
     39 	return func(enc *Encoder) {
     40 		enc.Lossless = true
     41 	}
     42 }
     43 
     44 // Encoder implements webp encoding of an image.
     45 type Encoder struct {
     46 	// Quality is in the range (0,1]. Values outside of this
     47 	// range will be treated as 1. Default 0.9.
     48 	Quality float32
     49 	// Lossless indicates whether to use the lossless compression
     50 	// strategy. If true, the Quality field is ignored.
     51 	Lossless bool
     52 }
     53 
     54 // Encode specified image as webp to w.
     55 // If the image is NRGBA, the pixel buffer will be encoded directly.
     56 // If the image is not NRGBA, it will be converted to NRGBA first.
     57 func (enc *Encoder) Encode(w io.Writer, m image.Image) error {
     58 	if enc.Quality <= 0.0 || enc.Quality > 1 {
     59 		enc.Quality = 1.0
     60 	}
     61 	return enc.encode(w, toNRGBA(m))
     62 }
     63 
     64 // toNRGBA returns m as *image.NRGBA, without copying when it already is one.
     65 func toNRGBA(m image.Image) *image.NRGBA {
     66 	if rgba, ok := m.(*image.NRGBA); ok {
     67 		return rgba
     68 	}
     69 	rgba := image.NewNRGBA(m.Bounds())
     70 	b := m.Bounds()
     71 	for y := b.Min.Y; y < b.Max.Y; y++ {
     72 		for x := b.Min.X; x < b.Max.X; x++ {
     73 			rgba.Set(x, y, m.At(x, y))
     74 		}
     75 	}
     76 	return rgba
     77 }
     78 
     79 func (enc *Encoder) encode(w io.Writer, m *image.NRGBA) error {
     80 	b, err := active()
     81 	if err != nil {
     82 		return err
     83 	}
     84 	return b.encode(w, m, enc.Quality)
     85 }