sticker

package module
v0.0.0-...-9fb4dda Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 6, 2026 License: GPL-3.0 Imports: 18 Imported by: 0

README

go-sticker

A high-performance Go library that processes images and animated content into WhatsApp-compliant stickers. The library is fast, accurate, and battle-tested against WhatsApp's strict sticker validation rules.

Features

  • Fully compliant static and animated WebP sticker generation
  • Transparent pipeline that leverages ffmpeg for maximum performance, with a pure-Go fallback for static images
  • Built-in size optimization loop out of the box
  • Simple thread-safe interface supporting concurrency limits

Prerequisites

It is highly recommended to install ffmpeg for performance and to enable animated sticker processing. Without ffmpeg, go-sticker will only process static images using standard Go libraries, and animation processing will fail.

# Ubuntu/Debian
sudo apt-get install ffmpeg

# MacOS
brew install ffmpeg

Quick Install

go get github.com/miruchigawa/sticker-go

Usage

package main

import (
	"context"
	"fmt"
	"os"
	"github.com/miruchigawa/sticker-go"
)

func main() {
	// Initialize a new processor
	proc := sticker.New()

	// Static image processing
	staticFile, _ := os.Open("image.png")
	staticSticker, err := proc.Process(context.Background(), staticFile, "image/png")
	if err != nil {
		panic(err)
	}
	os.WriteFile("static_sticker.webp", staticSticker, 0644)

	// Animated processing (requires ffmpeg)
	animFile, _ := os.Open("video.mp4")
	animSticker, err := proc.Process(context.Background(), animFile, "video/mp4")
	if err != nil {
		panic(err)
	}
	os.WriteFile("animated_sticker.webp", animSticker, 0644)
}
Validation
res, err := proc.Validate(staticSticker)
if err != nil {
    panic(err)
}
if res.Valid {
    fmt.Println("This is a valid WhatsApp sticker!")
} else {
    fmt.Println("Invalid sticker:", res.Errors)
}

ProcessOptions

You can customize processing behavior by modifying the defaults:

Property Description Default
Quality Target quality of the generated WebP (1-100) 80
Lossless Encode losslessly (increases file size) false
MaxFileSizeKB Size enforcement limit before resizing/re-encoding 100 (static) / 500 (animated)
FPS Target Frames Per Second for animations 15
MaxDuration Maximum allowed duration for an animation 3s
PadMode Rules on canvas fitting PadFit/PadFill/PadStretch/PadCrop PadFit (letterbox transparent)

WhatsApp Sticker Spec

All outputs comply strictly with:

Property Static Sticker Animated Sticker
Format .webp .webp
Max File Size <= 100 KB <= 500 KB
Canvas Size 512x512 512x512
Frames 1 8-30 FPS, <= 3 seconds
Background Alpha Transparent Alpha Transparent

Fallback Behavior

If ffmpeg is not found, go-sticker automatically degrades to use golang.org/x/image and github.com/chai2010/webp to handle static PNG/JPEG processing. Animations cannot be processed strictly in Go, so calling ProcessAnimation will return ErrFFmpegNotFound.

Benchmarks
BenchmarkStaticProcess-4              14          83998350 ns/op           86065 B/op        385 allocs/op
BenchmarkAnimProcess-4                 2         854138818 ns/op         1424972 B/op        800 allocs/op

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrFFmpegNotFound   = errors.New("sticker: ffmpeg binary not found in PATH")
	ErrTooLarge         = errors.New("sticker: output exceeds max file size after re-encoding")
	ErrInvalidFormat    = errors.New("sticker: unsupported or undetectable input format")
	ErrInvalidDimension = errors.New("sticker: cannot produce 512x512 from input")
	ErrContextCanceled  = errors.New("sticker: processing canceled via context")
)

Functions

This section is empty.

Types

type PadMode

type PadMode int

PadMode dictates how an image should be fitted into a 512x512 canvas.

const (
	PadFit     PadMode = iota // Letterbox/pillarbox with transparency (Default)
	PadFill                   // Cover crop (zoom in, center crop)
	PadStretch                // Stretch to fill (may distort)
	PadCrop                   // Crop from center
)

type ProcessOptions

type ProcessOptions struct {
	Quality       int           // WebP quality 1–100 (default: 80)
	Lossless      bool          // Use lossless WebP (increases size)
	MaxFileSizeKB int           // Enforce max KB (default: 100 for static, 500 for animated)
	FPS           int           // Target FPS for animated (default: 15)
	MaxDuration   time.Duration // Max animated duration (default: 3s)
	BgColor       *color.RGBA   // Optional background fill (nil = transparent)
	PadMode       PadMode       // How to fit into 512x512
	EXIF          *exif.Meta    // If non-nil, EXIF metadata is injected after encoding
}

ProcessOptions controls encoding behavior

type Processor

type Processor struct {
	// contains filtered or unexported fields
}

Processor is the main entry point to parse, process, and validate stickers.

func New

func New(configs ...ProcessorOption) *Processor

New creates a new sticker Processor.

func (*Processor) Process

func (p *Processor) Process(ctx context.Context, r io.Reader, mime string) ([]byte, error)

Process auto-detects if the input is animated or not. If mime indicates video/gif, it calls ProcessAnimation. Otherwise ProcessImage.

func (*Processor) ProcessAnimation

func (p *Processor) ProcessAnimation(ctx context.Context, r io.Reader) ([]byte, error)

ProcessAnimation converts an animated image/video into a WhatsApp-compliant animated WebP sticker.

func (*Processor) ProcessImage

func (p *Processor) ProcessImage(ctx context.Context, r io.Reader) ([]byte, error)

ProcessImage converts a static image into a WhatsApp-compliant WebP sticker.

func (*Processor) Validate

func (p *Processor) Validate(data []byte) (*ValidationResult, error)

Validate checks if the provided WebP data is a valid WhatsApp sticker

type ProcessorOption

type ProcessorOption func(*Processor)

ProcessorOption is a functional option for configuring a Processor

func WithBgColor

func WithBgColor(c *color.RGBA) ProcessorOption

WithBgColor sets an optional background fill color. Default: nil (transparent).

func WithEXIF

func WithEXIF(meta *exif.Meta) ProcessorOption

WithEXIF injects WhatsApp sticker EXIF metadata after encoding. If nil, no EXIF chunk is written. Default: nil.

func WithFPS

func WithFPS(fps int) ProcessorOption

WithFPS sets the target frame rate for animated stickers. Default: 15.

func WithLossless

func WithLossless(l bool) ProcessorOption

WithLossless enables lossless WebP encoding. Default: false.

func WithMaxConcurrency

func WithMaxConcurrency(max int) ProcessorOption

WithMaxConcurrency sets the maximum number of concurrent ffmpeg executions

func WithMaxDuration

func WithMaxDuration(d time.Duration) ProcessorOption

WithMaxDuration sets the maximum duration for animated stickers. Default: 3s.

func WithMaxFileSizeKB

func WithMaxFileSizeKB(kb int) ProcessorOption

WithMaxFileSizeKB sets the maximum output file size in kilobytes. Default: 100 for static, 500 for animated (auto-set by Process).

func WithPadMode

func WithPadMode(m PadMode) ProcessorOption

WithPadMode sets how the image is fitted into the 512×512 canvas. Default: PadFit.

func WithQuality

func WithQuality(q int) ProcessorOption

WithQuality sets the WebP encoding quality (1–100). Default: 80.

type ValidationResult

type ValidationResult struct {
	Valid      bool
	IsAnimated bool
	Width      int
	Height     int
	FileSizeKB float64
	FrameCount int
	FPS        float64
	Errors     []string
}

ValidationResult represents the output of a WhatsApp sticker validation

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL