imagine

package module
v0.0.0-...-4949b12 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2025 License: MIT Imports: 20 Imported by: 0

README

Imagine

Go Reference Go Report Card

A high-performance, plug-and-play image processing service for Go applications. Transform images on-the-fly using simple URL parameters.

Imagine Banner

✨ Features

  • 🚀 High Performance - Built on libvips through bimg for blazing-fast image operations
  • 🔌 Plug & Play - Works as a standalone server or embedded library
  • 🎨 Rich Transformations - Resize, crop, rotate, blur, sharpen, format conversion, and more
  • 💾 Flexible Storage - Multiple storage backends (Memory, Local, Redis, SQLite, BoltDB)
  • ⚡ Smart Caching - Multi-tier caching with configurable TTL
  • 🔗 URL-Based API - Transform images using simple query parameters
  • 📦 Zero Configuration - Sensible defaults that just work

📚 Table of Contents

🔧 Installation

Prerequisites

Imagine requires libvips to be installed on your system:

macOS:

brew install vips

Ubuntu/Debian:

sudo apt-get install libvips-dev

RHEL/CentOS:

sudo yum install vips-devel
Install Package
go get github.com/risico/imagine

🚀 Quick Start

As a Library
package main

import (
    "log"
    "net/http"
    
    "github.com/risico/imagine"
)

func main() {
    // Create imagine instance with defaults
    img, err := imagine.New(imagine.Params{
        Storage: imagine.NewLocalStorage(imagine.LocalStorageParams{
            Path: "./images",
        }),
        Cache: imagine.NewMemoryStorage(imagine.MemoryStoreParams{}),
    })
    if err != nil {
        log.Fatal(err)
    }

    // Register HTTP handlers
    http.HandleFunc("/upload", img.UploadHandlerFunc())
    http.HandleFunc("/images/", img.GetHandlerFunc())
    
    log.Println("Server running on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}
As a Standalone Server
# Install the CLI
go install github.com/risico/imagine/cmd@latest

# Start the server
imagine start --hostname localhost --port 8080

📖 Usage

As a Library
Basic Integration
import "github.com/risico/imagine"

// Initialize with custom configuration
img, err := imagine.New(imagine.Params{
    Storage: imagine.NewLocalStorage(imagine.LocalStorageParams{
        Path: "/var/images",
    }),
    Cache: imagine.NewRedisStorage(imagine.RedisStoreParams{
        Addr: "localhost:6379",
        TTL:  24 * time.Hour,
    }),
    MaxImageSize: 10 * 1024 * 1024, // 10MB
})
With Gin Framework
import (
    "github.com/gin-gonic/gin"
    "github.com/risico/imagine"
)

func main() {
    r := gin.Default()
    
    img, _ := imagine.New(imagine.Params{
        Storage: imagine.NewLocalStorage(imagine.LocalStorageParams{}),
        Cache:   imagine.NewMemoryStorage(imagine.MemoryStoreParams{}),
    })
    
    r.POST("/upload", gin.WrapF(img.UploadHandlerFunc()))
    r.GET("/images/*path", gin.WrapF(img.GetHandlerFunc()))
    
    r.Run(":8080")
}
Direct Image Processing
// Process an image directly
params := &imagine.ImageParams{
    Width:   800,
    Height:  600,
    Fit:     "cover",
    Quality: 85,
    Format:  "webp",
}

processedImage, err := img.Get("image-hash.jpg", params)
if err != nil {
    log.Fatal(err)
}

// processedImage.Image contains the processed bytes
// processedImage.Type contains the MIME type

🎯 URL Parameters

Transform images by adding query parameters to the image URL:

Parameter Type Description Example
w int Width in pixels ?w=800
h int Height in pixels ?h=600
fit string Resize mode: cover, contain, fill, inside, outside ?fit=cover
q, quality int JPEG/WebP quality (1-100) ?q=85
format string Output format: jpeg, png, webp, gif, tiff, avif ?format=webp
rotate int Rotation angle: 0, 90, 180, 270 ?rotate=90
flip string Flip direction: h (horizontal), v (vertical), both ?flip=h
blur float Gaussian blur (0.3-1000) ?blur=5
sharpen float Sharpen radius ?sharpen=2
grayscale bool Convert to grayscale ?grayscale
gravity string Crop position: center, north, south, east, west, smart ?gravity=smart
thumbnail int Square thumbnail size ?thumbnail=150
Example URLs
# Resize to 800x600 with smart cropping
/image.jpg?w=800&h=600&fit=cover&gravity=smart

# Create a 150x150 thumbnail
/image.jpg?thumbnail=150

# Convert to WebP with 85% quality
/image.jpg?format=webp&q=85

# Rotate 90 degrees and flip horizontally
/image.jpg?rotate=90&flip=h

# Apply blur effect and convert to grayscale
/image.jpg?blur=3&grayscale

# Complex transformation
/image.jpg?w=1920&h=1080&fit=cover&q=90&format=webp&sharpen=1&gravity=smart

💾 Storage Backends

Imagine supports multiple storage backends:

Memory Storage (Development)
storage := imagine.NewMemoryStorage(imagine.MemoryStoreParams{})
Local Filesystem
storage := imagine.NewLocalStorage(imagine.LocalStorageParams{
    Path: "/var/lib/imagine/images",
})
Redis
storage := imagine.NewRedisStorage(imagine.RedisStoreParams{
    Addr:     "localhost:6379",
    Password: "",
    DB:       0,
    TTL:      24 * time.Hour,
})
SQLite
storage := imagine.NewSQLiteStorage(imagine.SQLiteStoreParams{
    Path: "/var/lib/imagine/images.db",
})
BoltDB
storage := imagine.NewBoltStorage(imagine.BoltStoreParams{
    Path:   "/var/lib/imagine/bolt.db",
    Bucket: "images",
})

🎭 Examples

Upload an Image
curl -X POST -F "file=@photo.jpg" http://localhost:8080/upload
# Returns: abc123def456...
Transform Images
# Resize to 800x600
curl http://localhost:8080/images/abc123def456.jpg?w=800&h=600

# Create a WebP thumbnail
curl http://localhost:8080/images/abc123def456.jpg?thumbnail=200&format=webp

# Apply multiple transformations
curl http://localhost:8080/images/abc123def456.jpg?w=1920&h=1080&fit=cover&q=90&rotate=180&flip=v
Programmatic Upload
// Upload an image programmatically
imageData, _ := ioutil.ReadFile("photo.jpg")
hash, err := img.Upload(imageData)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Image uploaded: %s\n", hash)

📚 API Reference

Core Types
type Imagine struct {
    // Main application struct
}

type ImageParams struct {
    Width     int     // Target width
    Height    int     // Target height
    Quality   int     // JPEG/WebP quality (1-100)
    Format    string  // Output format
    Thumbnail int     // Thumbnail size
    Fit       string  // Resize mode
    Rotate    int     // Rotation angle
    Flip      string  // Flip direction
    Blur      float64 // Blur sigma
    Sharpen   float64 // Sharpen radius
    Grayscale bool    // Convert to grayscale
    Gravity   string  // Crop gravity
}

type ProcessedImage struct {
    Type  string // MIME type
    Image []byte // Image data
}
Main Methods
// Create a new Imagine instance
func New(params Params) (*Imagine, error)

// Process and retrieve an image
func (i *Imagine) Get(filename string, params *ImageParams) (*ProcessedImage, error)

// Upload a new image
func (i *Imagine) Upload(data []byte) (string, error)

// Parse URL parameters
func (i *Imagine) ParamsFromQueryString(query string) (*ImageParams, error)

// HTTP handlers
func (i *Imagine) UploadHandlerFunc() http.HandlerFunc
func (i *Imagine) GetHandlerFunc() http.HandlerFunc

🤝 Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request
Development
# Run tests
make test

# Run specific test
go test -run TestName ./...

# Build the project
go build ./...

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

📞 Support


Made with ❤️ by the Imagine community

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrImageNotFound = errors.New("image not found")
View Source
var ErrKeyNotFound = errors.New("key not found")

Functions

This section is empty.

Types

type BoltStoreParams

type BoltStoreParams struct {
	Path string
}

BoltStoreParams are the parameters for creating a new BoltStore

type Hasher

type Hasher interface {
	Hash([]byte) (string, error)
}

Hasher describes the hashing algorithm used to generate the image name. The default implementation is MD5Hasher. You can implement your own hashing algorithm by implementing this interface. For example, you can use SHA256 instead of MD5. You can also use a combination of hashing algorithms.

func MD5Hasher

func MD5Hasher() Hasher

MD5Hasher is the default implementation of Hasher. It uses MD5 to generate the image name.

func SHA256Hasher

func SHA256Hasher() Hasher

Sha256Hasher is the SHA256 implementation of Hasher.

type ImageInfo

type ImageInfo struct {
	Hash      string
	Filename  string
	Size      int64
	Width     int
	Height    int
	Format    string
	CreatedAt string
}

ImageInfo contains metadata about a stored image

type ImageParams

type ImageParams struct {
	Width, Height int

	// Quality is the quality of the image to be returned (1-100)
	Quality int

	// Format is the format of the image to be returned
	Format string

	// Thumbnail is the size of the thumbnail to be returned
	Thumbnail int

	// Fit mode: cover, contain, fill, inside, outside
	Fit string

	// Rotation angle in degrees (0, 90, 180, 270)
	Rotate int

	// Flip: h (horizontal), v (vertical), both
	Flip string

	// Blur sigma value (0.3 to 1000)
	Blur float64

	// Sharpen sigma value
	Sharpen float64

	// Convert to grayscale
	Grayscale bool

	// Gravity for smart cropping: center, north, south, east, west, etc.
	Gravity string

	// Preset for common configurations: thumb, small, medium, large, hero
	Preset string
}

Image params are the requested params to modify an image when retriving it

func (*ImageParams) CacheKey

func (ip *ImageParams) CacheKey(h Hasher) (string, error)

create a cache key from the image params

type Imagine

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

Imagine is our main application struct

func New

func New(params Params) (*Imagine, error)

New creates a new Imagine application

func (*Imagine) Delete

func (i *Imagine) Delete(filename string) error

Delete removes an image from storage

func (*Imagine) Get

func (i *Imagine) Get(filename string, params *ImageParams) (*ProcessedImage, error)

Get is the main entry point for the Imagine application. It returns the image as an array of bytes

func (*Imagine) GetHandlerFunc

func (i *Imagine) GetHandlerFunc() http.HandlerFunc

ProcessHandler handles the generation of images

func (*Imagine) ListImages

func (i *Imagine) ListImages() ([]ImageInfo, error)

ListImages returns information about all stored images Note: This requires the storage to be SQLite for now

func (*Imagine) ParamsFromQueryString

func (i *Imagine) ParamsFromQueryString(query string) (*ImageParams, error)

ParamsFromQueryString returns an ImageParams given a query string

func (*Imagine) Upload

func (i *Imagine) Upload(data []byte) (string, error)

func (*Imagine) UploadHandlerFunc

func (i *Imagine) UploadHandlerFunc() http.HandlerFunc

UploadHandler handles the upload of images

type LocalStoreParams

type LocalStoreParams struct {
	// Path is the path to the directory where the files will be stored
	Path string

	// TTL is the time to live for the file in seconds
	// This is to be set if you want to use this store as a caching mechanism
	TTL time.Duration
}

LocalStoreParams are the parameters for creating a new LocalStore

type MemoryStore

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

InMemoryStorage is a storage implementation that stores data in memory This should only be used for testing

func (*MemoryStore) Close

func (m *MemoryStore) Close() error

func (*MemoryStore) Delete

func (m *MemoryStore) Delete(key string) error

func (*MemoryStore) Get

func (m *MemoryStore) Get(key string) ([]byte, bool, error)

func (*MemoryStore) Set

func (m *MemoryStore) Set(key string, data []byte) error

type MemoryStoreParams

type MemoryStoreParams struct {
	TTL time.Duration
}

type Params

type Params struct {
	Cache   Store
	Storage Store
	Hasher  Hasher

	// MaxImageSize is the maximum size of an image in bytes
	MaxImageSize int
}

Params are the parameters used to create a new Imagine application

type ProcessedImage

type ProcessedImage struct {
	Type  string
	Image []byte
}

ProcessedImage is the result of processing an image

type SQLiteStoreParams

type SQLiteStoreParams struct {
	Path      string
	TableName string
}

type Store

type Store interface {
	Set(key string, data []byte) error
	Get(key string) (data []byte, ok bool, err error)
	Delete(key string) error

	io.Closer
}

Store is an interface for a key-value store. This interface is used by both the cache and the storage backends. Given the huge overlap between them it makes sense to have a common interface. For the Cache layer things like key expiration can be set at the store implementation level.

func NewBoltStore

func NewBoltStore(params BoltStoreParams) (Store, error)

NewBoltStore creates a new BoltStore

func NewInMemoryStorage

func NewInMemoryStorage(params MemoryStoreParams) Store

func NewLocalStorage

func NewLocalStorage(params LocalStoreParams) (Store, error)

func NewRedisStore

func NewRedisStore() Store

func NewSQLiteStorage

func NewSQLiteStorage(params SQLiteStoreParams) (Store, error)

Directories

Path Synopsis
src

Jump to

Keyboard shortcuts

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