You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
Tomas Aparicio 1d76750fb9
fix(test): resize
11 years ago
fixtures feat: add fixture 11 years ago
.editorconfig feat(#1): initial implementation 11 years ago
.gitignore refactor(resize) 11 years ago
.travis.yml feat(travis): add coveralls support 11 years ago
LICENSE feat(#1): initial implementation 11 years ago
README.md fix(#30): one concurrent thread by default 11 years ago
debug.go feat(version): bump 11 years ago
file.go refactor(file) 11 years ago
file_test.go refactor(resize): extract 11 years ago
image.go fix(#28): zoom requires extract params 11 years ago
image_test.go refactor(watermark): auto define width 11 years ago
metadata.go feat(#15): add benchmark tests 11 years ago
metadata_test.go fix(vips): panic error on exif orientation 11 years ago
options.go refactor: remove colorspace feature 11 years ago
resize.go fix(#31) 11 years ago
resize_test.go fix(test): resize 11 years ago
type.go feat(#15): add benchmark tests 11 years ago
type_test.go feat: add tests 11 years ago
version.go feat(version): bump 11 years ago
vips.go fix(#31) 11 years ago
vips.h fix(#30): one concurrent thread by default 11 years ago
vips_test.go feat(test): better coverage for vips interface 11 years ago

README.md

bimg Build Status GitHub release GoDoc Coverage Status

Small Go library for blazing fast and efficient image processing based on libvips using C bindings. It provides a clean, simple and fluent API in pure Go.

bimg was designed to be a small and efficient library with a generic and useful features.
It uses internally libvips, a powerful library written in C for binary image processing which requires a low memory footprint and it's typically 4x faster than using the quickest ImageMagick and GraphicsMagick settings or Go native image package, and in some cases it's even 8x faster processing JPEG images.

It can read JPEG, PNG, WEBP and TIFF formats and output to JPEG, PNG and WEBP, including conversion between them. It supports common image operations such as crop, resize, rotate, zoom, watermark...

For getting started, take a look to the examples and programmatic API documentation. If you're looking for a HTTP-based image processing solution, see imaginary.

bimg was heavily inspired in sharp, its homologous package built for node.js by Lovell Fuller.

Note: bimg is still beta. Do not use in compromised environments yet

Prerequisites

  • libvips v7.40.0+ (7.42.0+ recommended)
  • C compatible compiler such as gcc 4.6+ or clang 3.0+
  • Go 1.3+

Installation

go get -u gopkg.in/h2non/bimg.v0

libvips

Run the following script as sudo (supports OSX, Debian/Ubuntu, Redhat, Fedora, Amazon Linux):

curl -s https://raw.githubusercontent.com/lovell/sharp/master/preinstall.sh | sudo bash -

The install script requires curl and pkg-config

Supported image operations

  • Resize
  • Enlarge
  • Crop
  • Rotate (with auto-rotate based on EXIF orientation)
  • Flip (with auto-flip based on EXIF metadata)
  • Flop
  • Zoom
  • Thumbnail
  • Extract area
  • Watermark (fully customizable text-based)
  • Format conversion (with additional quality/compression settings)
  • EXIF metadata (size, alpha channel, profile, orientation...)

Performance

libvips is probably the faster open source solution for image processing. Here you can see some performance test comparisons for multiple scenarios:

Benchmarks

Tested using Go 1.4.2 and libvips-7.42.3 in OSX i7 2.7Ghz

BenchmarkResizeLargeJpeg  50    43400480 ns/op
BenchmarkResizePng        20    57592174 ns/op
BenchmarkResizeWebP       500    2872295 ns/op
BenchmarkConvertToJpeg    30    41835497 ns/op
BenchmarkConvertToPng     10   153382204 ns/op
BenchmarkConvertToWebp    10000   264542 ns/op
BenchmarkCropJpeg         30    52267699 ns/op
BenchmarkCropPng          30    56477454 ns/op
BenchmarkCropWebP         5000    274302 ns/op
BenchmarkExtractJpeg      50    27827670 ns/op
BenchmarkExtractPng       2000    769761 ns/op
BenchmarkExtractWebp      3000    513954 ns/op
BenchmarkZoomJpeg         10   159272494 ns/op
BenchmarkZoomPng          20    65771476 ns/op
BenchmarkZoomWebp         5000    368327 ns/op
BenchmarkWatermarkJpeg    100   10026033 ns/op
BenchmarkWatermarPng      200    7350821 ns/op
BenchmarkWatermarWebp     200    9014197 ns/op
ok 30.698s

API

Examples

import (
  "fmt"
  "os"
  "gopkg.in/h2non/bimg.v0"
)

Resize

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

newImage, err := bimg.NewImage(buffer).Resize(800, 600)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

size, err := bimg.NewImage(newImage).Size()
if size.Width == 400 && size.Height == 300 {
  fmt.Println("The image size is valid")
}

bimg.Write("new.jpg", newImage)

Rotate

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

newImage, err := bimg.NewImage(buffer).Rotate(90)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

bimg.Write("new.jpg", newImage)

Convert

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

newImage, err := bimg.NewImage(buffer).Convert(bimg.PNG)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

if bimg.NewImage(newImage).Type() == "png" {
  fmt.Fprintln(os.Stderr, "The image was converted into png")
}

Custom options

See Options struct to discover all the available fields

options := bimg.Options{
  Width:        800,
  Height:       600,
  Crop:         true,
  Quality:      95,
  Rotate:       180,
}

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

newImage, err := bimg.NewImage(buffer).Process(options)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

bimg.Write("new.jpg", newImage)

Watermark

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

options := bimg.Watermark{
  Watermark{
    Text:       "Chuck Norris (c) 2315",
    Opacity:    0.25,
    Width:      200,
    DPI:        100,
    Margin:     150,
    Font:       "sans bold 12",
    Background: bimg.Color{255, 255, 255},
  }
}

newImage, err := bimg.NewImage(buffer).Watermark(options)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

bimg.Write("new.jpg", newImage)

Fluent interface

buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

image := bimg.NewImage(buffer)

// first crop image
_, err := image.CropByWidth(300)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

// then flip it
newImage, err := image.Flip()
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

// save the cropped and flipped image
bimg.Write("new.jpg", newImage)

Debugging

Run the process passing the DEBUG environment variable

DEBUG=* ./app 

Enable libvips traces (note that a lot of data will be written in stdout):

VIPS_TRACE=1 ./app 

func DetermineImageTypeName

func DetermineImageTypeName(buf []byte) string

Determines the image type format by name (jpeg, png, webp or tiff)

func Initialize

func Initialize()

Explicit thread-safe start of libvips. Only call this function if you've previously shutdown libvips

func IsTypeNameSupported

func IsTypeNameSupported(t string) bool

Check if a given image type name is supported

func IsTypeSupported

func IsTypeSupported(t ImageType) bool

Check if a given image type is supported

func PrintMemoryStats

func PrintMemoryStats()

Print Go memory and garbage collector stats. Useful for debugging

func Read

func Read(path string) ([]byte, error)

func Resize

func Resize(buf []byte, o Options) ([]byte, error)

func Shutdown

func Shutdown()

Explicit thread-safe libvips shutdown. Call this to drop caches. If libvips was already initialized, the function is no-op

func VipsDebug

func VipsDebug()

Output to stdout vips collected data. Useful for debugging

func Write

func Write(path string, buf []byte) error

type Angle

type Angle int
const (
  D0   Angle = C.VIPS_ANGLE_D0
  D90  Angle = C.VIPS_ANGLE_D90
  D180 Angle = C.VIPS_ANGLE_D180
  D270 Angle = C.VIPS_ANGLE_D270
)

type Color

type Color struct {
  R, G, B uint8
}

Color represents a traditional RGB color scheme

type Direction

type Direction int
const (
  HORIZONTAL Direction = C.VIPS_DIRECTION_HORIZONTAL
  VERTICAL   Direction = C.VIPS_DIRECTION_VERTICAL
)

type Gravity

type Gravity int
const (
  CENTRE Gravity = iota
  NORTH
  EAST
  SOUTH
  WEST
)

type Image

type Image struct {
}

func NewImage

func NewImage(buf []byte) *Image

Creates a new image

func (*Image) Convert

func (i *Image) Convert(t ImageType) ([]byte, error)

Convert image to another format

func (*Image) Crop

func (i *Image) Crop(width, height int, gravity Gravity) ([]byte, error)

Crop the image to the exact size specified

func (*Image) CropByHeight

func (i *Image) CropByHeight(height int) ([]byte, error)

Crop an image by height (auto width)

func (*Image) CropByWidth

func (i *Image) CropByWidth(width int) ([]byte, error)

Crop an image by width (auto height)

func (*Image) Enlarge

func (i *Image) Enlarge(width, height int) ([]byte, error)

Enlarge the image from the by X/Y axis

func (*Image) Extract

func (i *Image) Extract(top, left, width, height int) ([]byte, error)

Extract area from the by X/Y axis

func (*Image) Flip

func (i *Image) Flip() ([]byte, error)

Flip the image about the vertical Y axis

func (*Image) Flop

func (i *Image) Flop() ([]byte, error)

Flop the image about the horizontal X axis

func (*Image) Image

func (i *Image) Image() []byte

Get image buffer

func (*Image) Metadata

func (i *Image) Metadata() (ImageMetadata, error)

Get image metadata (size, alpha channel, profile, EXIF rotation)

func (*Image) Process

func (i *Image) Process(o Options) ([]byte, error)

Transform the image by custom options

func (*Image) Resize

func (i *Image) Resize(width, height int) ([]byte, error)

Resize the image to fixed width and height

func (*Image) Rotate

func (i *Image) Rotate(a Angle) ([]byte, error)

Rotate the image by given angle degrees (0, 90, 180 or 270)

func (*Image) Size

func (i *Image) Size() (ImageSize, error)

Get image size

func (*Image) Thumbnail

func (i *Image) Thumbnail(pixels int) ([]byte, error)

Thumbnail the image by the a given width by aspect ratio 4:4

func (*Image) Type

func (i *Image) Type() string

Get image type format (jpeg, png, webp, tiff)

func (*Image) Watermark

func (i *Image) Watermark(w Watermark) ([]byte, error)

Add text as watermark on the given image

func (*Image) Zoom

func (i *Image) Zoom(level int) ([]byte, error)

Zoom the image by the given factor

type ImageMetadata

type ImageMetadata struct {
  Orientation int
  Channels    int
  Alpha       bool
  Profile     bool
  Type        string
  Space       string
  Size        ImageSize
}

func Metadata

func Metadata(buf []byte) (ImageMetadata, error)

Extract the image metadata (size, type, alpha channel, profile, EXIF orientation...)

type ImageSize

type ImageSize struct {
  Width  int
  Height int
}

func Size

func Size(buf []byte) (ImageSize, error)

Get the image size by width and height pixels

type ImageType

type ImageType int
const (
  UNKNOWN ImageType = iota
  JPEG
  WEBP
  PNG
  TIFF
  MAGICK
)

func DetermineImageType

func DetermineImageType(buf []byte) ImageType

Determines the image type format (jpeg, png, webp or tiff)

type Interpolator

type Interpolator int
const (
  BICUBIC Interpolator = iota
  BILINEAR
  NOHALO
)

func (Interpolator) String

func (i Interpolator) String() string

type Options

type Options struct {
  Height       int
  Width        int
  AreaHeight   int
  AreaWidth    int
  Top          int
  Left         int
  Extend       int
  Quality      int
  Compression  int
  Zoom         int
  Crop         bool
  Enlarge      bool
  Embed        bool
  Flip         bool
  Flop         bool
  NoAutoRotate bool
  Rotate       Angle
  Gravity      Gravity
  Watermark    Watermark
  Type         ImageType
  Interpolator Interpolator
}

type VipsMemoryInfo

type VipsMemoryInfo struct {
  Memory          int64
  MemoryHighwater int64
  Allocations     int64
}

func VipsMemory

func VipsMemory() VipsMemoryInfo

Get memory info stats from vips (cache size, memory allocs...)

type Watermark

type Watermark struct {
  Width       int
  DPI         int
  Margin      int
  Opacity     float32
  NoReplicate bool
  Text        string
  Font        string
  Background  Color
}

Special Thanks

License

MIT - Tomas Aparicio

views