bimg

package module
Version: v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Jun 22, 2016 License: MIT Imports: 10 Imported by: 0

README

bimg Build Status GoDoc Go Report Card Coverage Status

Small Go package for fast high-level image processing using libvips via C bindings, providing a simple, elegant and fluent programmatic API.

bimg was designed to be a small and efficient library supporting a common set of image operations such as crop, resize, rotate, zoom or watermark. It can read JPEG, PNG, WEBP and TIFF formats and output to JPEG, PNG and WEBP, including conversion across them.

bimg uses internally libvips, a powerful library written in C for 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.

If you're looking for an HTTP based image processing solution, see imaginary.

bimg was heavily inspired in sharp, its homologous package built for node.js. bimg is used in production environments for more than a year processing thousands of images per day.

v1 notice: bimg introduces some minor breaking changes in v1 release. If you're using gopkg.in, you can still rely in the v0 without worrying about breaking changes.

Contents

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 (text only)
  • Gaussian blur effect
  • Custom output color space (RGB, grayscale...)
  • Format conversion (with additional quality/compression settings)
  • EXIF metadata (size, alpha channel, profile, orientation...)

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.v1
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 -

If you wanna take the advantage of OpenSlide, simply add --with-openslide to enable it:

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

The install script requires curl and pkg-config

For platform specific installations, see Mac OS tips or Windows tips

Performance

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

Benchmark

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

BenchmarkRotateJpeg-8     	      20	  64686945 ns/op
BenchmarkResizeLargeJpeg-8	      20	  63390416 ns/op
BenchmarkResizePng-8      	     100	  18147294 ns/op
BenchmarkResizeWebP-8     	     100	  20836741 ns/op
BenchmarkConvertToJpeg-8  	     100	  12831812 ns/op
BenchmarkConvertToPng-8   	      10	 128901422 ns/op
BenchmarkConvertToWebp-8  	      10	 204027990 ns/op
BenchmarkCropJpeg-8       	      30	  59068572 ns/op
BenchmarkCropPng-8        	      10	 117303259 ns/op
BenchmarkCropWebP-8       	      10	 107060659 ns/op
BenchmarkExtractJpeg-8    	      50	  30708919 ns/op
BenchmarkExtractPng-8     	    3000	    595546 ns/op
BenchmarkExtractWebp-8    	    3000	    386379 ns/op
BenchmarkZoomJpeg-8       	      10	 160005424 ns/op
BenchmarkZoomPng-8        	      30	  44561047 ns/op
BenchmarkZoomWebp-8       	      10	 126732678 ns/op
BenchmarkWatermarkJpeg-8  	      20	  79006133 ns/op
BenchmarkWatermarPng-8    	     200	   8197291 ns/op
BenchmarkWatermarWebp-8   	      30	  49360369 ns/op

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")
}
Force resize

Force resize operation without perserving the aspect ratio:

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

newImage, err := bimg.NewImage(buffer).ForceResize(1000, 500)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}
  
size := bimg.Size(newImage)
if size.Width != 1000 || size.Height != 500 {
  fmt.Fprintln(os.Stderr, "Incorrect image size")
}
Custom colour space (black & white)
buffer, err := bimg.Read("image.jpg")
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}

newImage, err := bimg.NewImage(buffer).Colourspace(bimg.INTERPRETATION_B_W)
if err != nil {
  fmt.Fprintln(os.Stderr, err)
}
  
colourSpace, _ := bimg.ImageInterpretation(newImage)
if colourSpace != bimg.INTERPRETATION_B_W {
  fmt.Fprintln(os.Stderr, "Invalid colour space")
}
Custom options

See Options struct to discover all the available fields

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

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)
}

watermark := bimg.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(watermark)
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=bimg ./app 

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

VIPS_TRACE=1 ./app 

You can also dump a core on failure, as John Cuppit said:

g_log_set_always_fatal(
                G_LOG_FLAG_RECURSION |
                G_LOG_FLAG_FATAL |
                G_LOG_LEVEL_ERROR |
                G_LOG_LEVEL_CRITICAL |
                G_LOG_LEVEL_WARNING );

Or set the G_DEBUG environment variable:

export G_DEBUG=fatal-warnings,fatal-criticals

API

See godoc reference for detailed API documentation.

Credits

People who recurrently contributed to improve bimg in some way.

Thank you!

License

MIT - Tomas Aparicio

views

Documentation

Index

Constants

View Source
const (
	// Quality defines the default JPEG quality to be used.
	Quality = 80
	// MaxSize defines the maximum pixels width or height supported.
	MaxSize = 16383
)
View Source
const HasMagickSupport = int(C.VIPS_MAGICK_SUPPORT) == 1

HasMagickSupport exposes if the current libvips compilation supports libmagick bindings.

View Source
const Version = "1.0.1"

Version represents the current package semantic version.

View Source
const VipsVersion = string(C.VIPS_VERSION)

VipsVersion exposes the current libvips semantic version

Variables

View Source
var ColorBlack = Color{0, 0, 0}

ColorBlack is a shortcut to black RGB color representation.

View Source
var ImageTypes = map[ImageType]string{
	JPEG:   "jpeg",
	PNG:    "png",
	WEBP:   "webp",
	TIFF:   "tiff",
	MAGICK: "magick",
}

ImageTypes stores as pairs of image types supported and its alias names.

View Source
var WatermarkFont = "sans 10"

WatermarkFont defines the default watermark font to be used.

Functions

func ColourspaceIsSupported

func ColourspaceIsSupported(buf []byte) (bool, error)

ColourspaceIsSupported checks if the image colourspace is supported by libvips.

func DetermineImageTypeName

func DetermineImageTypeName(buf []byte) string

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

func ImageTypeName

func ImageTypeName(t ImageType) string

ImageTypeName is used to get the human friendly name of an image format.

func Initialize

func Initialize()

Initialize is used to explicitly start libvips in thread-safe way. Only call this function if you have previously turned off libvips.

func IsTypeNameSupported

func IsTypeNameSupported(t string) bool

IsTypeNameSupported checks if a given image type name is supported

func IsTypeSupported

func IsTypeSupported(t ImageType) bool

IsTypeSupported checks if a given image type is supported

func Read

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

Read reads all the content of the given file path and returns it as byte buffer.

func Resize

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

Resize is used to transform a given image as byte buffer with the passed options.

func Shutdown

func Shutdown()

Shutdown is used to shutdown libvips in a thread-safe way. You can call this to drop caches as well. If libvips was already initialized, the function is no-op

func VipsDebugInfo

func VipsDebugInfo()

VipsDebugInfo outputs to stdout libvips collected data. Useful for debugging.

func Write

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

Write writes the given byte buffer into disk to the given file path.

Types

type Angle

type Angle int

Angle represents the image rotation angle value.

const (
	// D0 represents the rotation angle 0 degrees.
	D0 Angle = 0
	// D90 represents the rotation angle 90 degrees.
	D90 Angle = 90
	// D180 represents the rotation angle 180 degrees.
	D180 Angle = 180
	// D270 represents the rotation angle 270 degrees.
	D270 Angle = 270
)

type Color

type Color struct {
	R, G, B uint8
}

Color represents a traditional RGB color scheme.

type Direction

type Direction int

Direction represents the image direction value.

const (
	// Horizontal represents the orizontal image direction value.
	Horizontal Direction = C.VIPS_DIRECTION_HORIZONTAL
	// Vertical represents the vertical image direction value.
	Vertical Direction = C.VIPS_DIRECTION_VERTICAL
)

type GaussianBlur

type GaussianBlur struct {
	Sigma   float64
	MinAmpl float64
}

GaussianBlur represents the gaussian image transformation values.

type Gravity

type Gravity int

Gravity represents the image gravity value.

const (
	// GravityCentre represents the centre value used for image gravity orientation.
	GravityCentre Gravity = iota
	// GravityNorth represents the north value used for image gravity orientation.
	GravityNorth
	// GravityEast represents the east value used for image gravity orientation.
	GravityEast
	// GravitySouth represents the south value used for image gravity orientation.
	GravitySouth
	// GravityWest represents the west value used for image gravity orientation.
	GravityWest
)

type Image

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

Image provides a simple method DSL to transform a given image as byte buffer.

func NewImage

func NewImage(buf []byte) *Image

NewImage creates a new Image struct with method DSL.

func (*Image) Colourspace

func (i *Image) Colourspace(c Interpretation) ([]byte, error)

Colourspace performs a color space conversion bsaed on the given interpretation.

func (*Image) ColourspaceIsSupported

func (i *Image) ColourspaceIsSupported() (bool, error)

ColourspaceIsSupported checks if the current image color space is supported.

func (*Image) Convert

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

Convert converts image to another format.

func (*Image) Crop

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

Crop crops the image to the exact size specified.

func (*Image) CropByHeight

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

CropByHeight crops an image by height (auto width).

func (*Image) CropByWidth

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

CropByWidth crops an image by width only param (auto height).

func (*Image) Enlarge

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

Enlarge enlarges the image by width and height. Aspect ratio is maintained.

func (*Image) EnlargeAndCrop

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

EnlargeAndCrop enlarges the image by width and height with additional crop transformation.

func (*Image) Extract

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

Extract area from the by X/Y axis in the current image.

func (*Image) Flip

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

Flip flips the image about the vertical Y axis.

func (*Image) Flop

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

Flop flops the image about the horizontal X axis.

func (*Image) ForceResize

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

ForceResize resizes with custom size (aspect ratio won't be maintained).

func (*Image) Image

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

Image returns the current resultant image image buffer.

func (*Image) Interpretation

func (i *Image) Interpretation() (Interpretation, error)

Interpretation gets the image interpretation type. See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation

func (*Image) Metadata

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

Metadata returns the image metadata (size, alpha channel, profile, EXIF rotation).

func (*Image) Process

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

Process processes the image based on the given transformation options, talking with libvips bindings accordingly and returning the resultant image buffer.

func (*Image) Resize

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

Resize resizes the image to fixed width and height.

func (*Image) ResizeAndCrop

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

ResizeAndCrop resizes the image to fixed width and height with additional crop transformation.

func (*Image) Rotate

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

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

func (*Image) Size

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

Size returns the image size as form of width and height pixels.

func (*Image) Thumbnail

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

Thumbnail creates a thumbnail of the image by the a given width by aspect ratio 4:4.

func (*Image) Type

func (i *Image) Type() string

Type returns the image type format (jpeg, png, webp, tiff).

func (*Image) Watermark

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

Watermark adds text as watermark on the given image.

func (*Image) Zoom

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

Zoom zooms the image by the given factor. You should probably call Extract() before.

type ImageMetadata

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

ImageMetadata represents the basic metadata fields

func Metadata

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

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

type ImageSize

type ImageSize struct {
	Width  int
	Height int
}

ImageSize represents the image width and height values

func Size

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

Size returns the image size by width and height pixels.

type ImageType

type ImageType int

ImageType represents an image type value.

const (
	// UNKNOWN represents an unknow image type value.
	UNKNOWN ImageType = iota
	// JPEG represents the JPEG image type.
	JPEG
	// WEBP represents the WEBP image type.
	WEBP
	// PNG represents the PNG image type.
	PNG
	// TIFF represents the TIFF image type.
	TIFF
	// MAGICK represents the libmagick compatible genetic image type.
	MAGICK
)

func DetermineImageType

func DetermineImageType(buf []byte) ImageType

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

type Interpolator

type Interpolator int

Interpolator represents the image interpolation value.

const (
	// Bicubic interpolation value.
	Bicubic Interpolator = iota
	// Bilinear interpolation value.
	Bilinear
	// Nohalo interpolation value.
	Nohalo
)

func (Interpolator) String

func (i Interpolator) String() string

type Interpretation

type Interpretation int

Interpretation represents the image interpretation type. See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation

const (
	// InterpretationError points to the libvips interpretation error type.
	InterpretationError Interpretation = C.VIPS_INTERPRETATION_ERROR
	// InterpretationMultiband points to its libvips interpretation equivalent type.
	InterpretationMultiband Interpretation = C.VIPS_INTERPRETATION_MULTIBAND
	// InterpretationBW points to its libvips interpretation equivalent type.
	InterpretationBW Interpretation = C.VIPS_INTERPRETATION_B_W
	// InterpretationCMYK points to its libvips interpretation equivalent type.
	InterpretationCMYK Interpretation = C.VIPS_INTERPRETATION_CMYK
	// InterpretationRGB points to its libvips interpretation equivalent type.
	InterpretationRGB Interpretation = C.VIPS_INTERPRETATION_RGB
	// InterpretationSRGB points to its libvips interpretation equivalent type.
	InterpretationSRGB Interpretation = C.VIPS_INTERPRETATION_sRGB
	// InterpretationRGB16 points to its libvips interpretation equivalent type.
	InterpretationRGB16 Interpretation = C.VIPS_INTERPRETATION_RGB16
	// InterpretationGREY16 points to its libvips interpretation equivalent type.
	InterpretationGREY16 Interpretation = C.VIPS_INTERPRETATION_GREY16
	// InterpretationScRGB points to its libvips interpretation equivalent type.
	InterpretationScRGB Interpretation = C.VIPS_INTERPRETATION_scRGB
	// InterpretationLAB points to its libvips interpretation equivalent type.
	InterpretationLAB Interpretation = C.VIPS_INTERPRETATION_LAB
	// InterpretationXYZ points to its libvips interpretation equivalent type.
	InterpretationXYZ Interpretation = C.VIPS_INTERPRETATION_XYZ
)

func ImageInterpretation

func ImageInterpretation(buf []byte) (Interpretation, error)

ImageInterpretation returns the image interpretation type. See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation

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
	Force          bool
	NoAutoRotate   bool
	NoProfile      bool
	Interlace      bool
	Rotate         Angle
	Background     Color
	Gravity        Gravity
	Watermark      Watermark
	Type           ImageType
	Interpolator   Interpolator
	Interpretation Interpretation
	GaussianBlur   GaussianBlur
	Sharpen        Sharpen
}

Options represents the supported image transformation options.

type Sharpen

type Sharpen struct {
	Radius int
	X1     float64
	Y2     float64
	Y3     float64
	M1     float64
	M2     float64
}

Sharpen represents the image sharp transformation options.

type VipsMemoryInfo

type VipsMemoryInfo struct {
	Memory          int64
	MemoryHighwater int64
	Allocations     int64
}

VipsMemoryInfo represents the memory stats provided by libvips.

func VipsMemory

func VipsMemory() VipsMemoryInfo

VipsMemory gets memory info stats from libvips (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
}

Watermark represents the text-based watermark supported options.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL