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 }