nativewebp

repository·main·Indexed 19 days ago

https://github.com/hugosmits86/nativewebp

A native Go implementation of a WebP encoder that requires no external C dependencies. It specifically targets lossless WebP (VP8L) encoding for static images and animations. The library provides functions for encoding images and animations, retrieving metadata via DecodeConfig, and a specialized DecodeIgnoreAlphaFlag function to handle VP8L images with transparency issues encountered in the standard x/image/webp package.

Tokens
2.4K
Snippets
11
Records
12
Agent score
66%

What's inside nativewebp

  1. Encode a static image to WebP

    main

    Use nativewebp.Encode to encode a single image. It accepts an io.Writer, an image.Image, and an optional options object (pass nil to use defaults). Note that the current encoder only supports WebP lossless (VP8L) images.

    file, err := os.Create(name)
    if err != nil {
      log.Fatalf("Error creating file %s: %v", name, err)
    }
    defer file.Close()
    
    err = nativewebp.Encode(file, img, nil)
    if err != nil {
      log.Fatalf("Error encoding image to WebP: %v", err)
    }
  2. Encode a WebP animation

    main

    To create an animated WebP, use nativewebp.EncodeAll. You must provide a nativewebp.Animation struct containing the frames, durations, and disposal methods.

    file, err := os.Create(name)
    if err != nil {
      log.Fatalf("Error creating file %s: %v", name, err)
    }
    defer file.Close()
    
    ani := nativewebp.Animation{
      Images: []image.Image{
        frame1,
        frame2,
      },
      Durations: []uint {
        100,
        100,
      },
      Disposals: []uint {
        0,
        0,
      },
      LoopCount: 0,
      BackgroundColor: 0xffffffff,
    }
    
    err = nativewebp.EncodeAll(file, &ani, nil)
    if err != nil {
      log.Fatalf("Error encoding WebP animation: %v", err)
    }
  3. Configure WebP encoding options

    main

    The Options struct allows you to tune the encoding process:

    • UseExtendedFormat (bool): If true, wraps the VP8L frame inside a VP8X container to enable metadata support (EXIF, ICC, XMP).
    • CompressionLevel (CompressionLevel): Controls the trade-off between encoding speed and file size. Higher levels increase CPU usage and encoding time but may improve compression.
    type Options struct {
        UseExtendedFormat   bool
        CompressionLevel    CompressionLevel
    }
  4. Encode an animation to WebP

    main

    Use the EncodeAll function to encode a sequence of frames as a WebP animation. This function automatically uses the VP8X container, which is required for animation features like looping and frame timing. Each frame is individually compressed using the VP8L (lossless) format.

    Parameters:

    • w: The destination io.Writer.
    • ani: A pointer to an Animation struct containing the frame sequence and settings.
    • o: A pointer to Options for encoding effort (can be nil).

    Note: UseExtendedFormat in the Options struct is currently unused for animations but is accepted for API consistency.

    ani := &nativewebp.Animation{
        Images:          []image.Image{img1, img2},
        Durations:       []uint{100, 200}, // milliseconds
        Disposals:       []uint{0, 1},     // 0 = keep, 1 = clear to background
        LoopCount:       0,               // 0 = infinite
        BackgroundColor: 0xFF000000,       // BGRA order
    }
    
    err := nativewebp.EncodeAll(w, ani, &nativewebp.Options{
        CompressionLevel: nativewebp.DefaultCompression,
    })
  5. Encode a single image to WebP

    main

    Use the Encode function to write a single image.Image to an io.Writer in WebP format. This function uses the VP8L (lossless) encoding method.

    To enable metadata support (such as EXIF, ICC color profiles, or XMP), set UseExtendedFormat: true in the Options struct. This wraps the VP8L frame in a VP8X container. Note that VP8L natively supports transparency, so UseExtendedFormat is not required for alpha channel support.

    Parameters:

    • w: The destination io.Writer.
    • img: The input image.Image.
    • o: A pointer to Options for configuration (can be nil to use defaults).
    err := nativewebp.Encode(w, img, &nativewebp.Options{
        UseExtendedFormat: true,
        CompressionLevel:  nativewebp.BestCompression,
    })
  6. Decode a WebP image with Decode()

    main

    Use Decode to read a WebP image from an io.Reader and return it as an image.Image. This function supports both lossy and lossless WebP formats and acts as a wrapper around golang.org/x/image/webp.

    import (
        "os"
        "github.com/hugosmits86/nativewebp"
    )
    
    func main() {
        f, err := os.Open("image.webp")
        if err != nil {
            panic(err)
        }
        defer f.Close()
    
        img, err := nativewebp.Decode(f)
        if err != nil {
            panic(err)
        }
        // Use img (image.Image)
    }
  7. Decode VP8L images with transparency using DecodeIgnoreAlphaFlag()

    main

    Use DecodeIgnoreAlphaFlag to decode WebP images that use the VP8L (lossless) format with the VP8X alpha flag.

    This function resolves an issue where the standard x/image/webp package rejects VP8L images that have the transparency flag set but lack an explicit ALPHA chunk. It works by manually clearing the alpha flag in the bitstream before passing it to the underlying decoder.

    Note: This function reads the entire image into memory (up to a limit of 256 MiB) to perform the bitstream modification.

    import (
        "os"
        "github.com/hugosmits86/nativewebp"
    )
    
    func main() {
        f, err := os.Open("lossless_with_alpha.webp")
        if err != nil {
            panic(err)
        }
        defer f.Close()
    
        // Use this if standard Decode fails due to VP8X/VP8L alpha flag issues
        img, err := nativewebp.DecodeIgnoreAlphaFlag(f)
        if err != nil {
            panic(err)
        }
        // Use img (image.Image)
    }
  8. Retrieve WebP metadata with DecodeConfig()

    main

    Use DecodeConfig to read image configuration (dimensions and color model) from an io.Reader without performing a full image decode. This is efficient for inspecting image metadata.

    import (
        "os"
        "image"
        "github.com/hugosmits86/nativewebp"
    )
    
    func main() {
        f, err := os.Open("image.webp")
        if err != nil {
            panic(err)
        }
        defer f.Close()
    
        config, err := nativewebp.DecodeConfig(f)
        if err != nil {
            panic(err)
        }
        // Use config.Width, config.Height, etc.
    }
  9. Configure WebP animation settings

    main

    The Animation struct defines the sequence and behavior of a WebP animation:

    • Images: A slice of image.Image frames.
    • Durations: A slice of uint representing the display time for each frame in milliseconds. Must match the length of Images.
    • Disposals: A slice of uint defining how frames are handled after display (0 = keep, 1 = clear to background). Must match the length of Images.
    • LoopCount: A uint16 specifying how many times the animation repeats (0 = infinite).
    • BackgroundColor: A uint32 representing the canvas background color in BGRA order, used during clear operations.
    type Animation struct {
        Images              []image.Image
        Durations           []uint
        Disposals           []uint
        LoopCount           uint16
        BackgroundColor     uint32
    }
  10. Set WebP compression levels

    main

    The CompressionLevel type defines the effort used by the encoder. Use the following constants:

    • BestSpeed (0): Lowest compression effort, fastest encoding.
    • DefaultCompression (4): The standard balance between speed and size.
    • BestCompression (6): Highest compression effort, smallest file size, slowest encoding.
    const (
    	DefaultCompression CompressionLevel = 4
    	BestSpeed          CompressionLevel = 0
    	BestCompression    CompressionLevel = 6
    )