Convert Figma logo to code with AI

h2non logobimg

Go package for fast high-level image processing powered by libvips C library

2,750
344
2,750
174

Top Related Projects

Fast, simple, scalable, Docker-ready HTTP microservice for high-level image processing

Fast, dependency-free Go package to infer binary file types based on the magic numbers header signature

2,115

HTTP traffic mocking and testing made easy in Go ༼ʘ̚ل͜ʘ̚༽

Plugin-driven, extensible HTTP client toolkit for Go

Quick Overview

The bimg library is a high-performance image processing library for Go, providing a simple and efficient API for common image manipulation tasks such as resizing, cropping, rotating, and converting between various image formats.

Pros

  • High Performance: The library is built on top of the popular libvips library, which is known for its speed and efficiency in image processing.
  • Extensive Functionality: bimg supports a wide range of image processing operations, including resizing, cropping, rotating, and converting between various image formats.
  • Simple and Intuitive API: The library provides a clean and easy-to-use API, making it straightforward to integrate into your Go projects.
  • Cross-Platform Compatibility: bimg is designed to be cross-platform, with support for Windows, macOS, and Linux.

Cons

  • Dependency on libvips: The library relies on the libvips library, which may not be available on all systems or may require additional setup.
  • Limited Documentation: The project's documentation could be more comprehensive, which may make it more challenging for new users to get started.
  • Potential Performance Issues: While the library is generally fast, it may encounter performance issues when processing very large or complex images.
  • Limited Community Support: The project has a relatively small community, which may limit the availability of support and resources for users.

Code Examples

Here are a few examples of how to use the bimg library:

  1. Resizing an Image:
package main

import (
    "fmt"
    "github.com/h2non/bimg"
)

func main() {
    buffer, err := bimg.Read("input.jpg")
    if err != nil {
        fmt.Println(err)
        return
    }

    newBuffer, err := bimg.Resize(buffer, bimg.Options{
        Width:   800,
        Height:  600,
        Gravity: bimg.GravityCentre,
        Interpolator: bimg.Bicubic,
    })
    if err != nil {
        fmt.Println(err)
        return
    }

    err = bimg.Write("output.jpg", newBuffer)
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("Image resized successfully!")
}
  1. Cropping an Image:
package main

import (
    "fmt"
    "github.com/h2non/bimg"
)

func main() {
    buffer, err := bimg.Read("input.jpg")
    if err != nil {
        fmt.Println(err)
        return
    }

    newBuffer, err := bimg.Crop(buffer, bimg.Options{
        Width:   800,
        Height:  600,
        Top:     100,
        Left:    100,
        Gravity: bimg.GravityCentre,
    })
    if err != nil {
        fmt.Println(err)
        return
    }

    err = bimg.Write("output.jpg", newBuffer)
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("Image cropped successfully!")
}
  1. Converting an Image to a Different Format:
package main

import (
    "fmt"
    "github.com/h2non/bimg"
)

func main() {
    buffer, err := bimg.Read("input.jpg")
    if err != nil {
        fmt.Println(err)
        return
    }

    newBuffer, err := bimg.Convert(buffer, bimg.PNG)
    if err != nil {
        fmt.Println(err)
        return
    }

    err = bimg.Write("output.png", newBuffer)
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println("Image converted successfully!")
}

Getting Started

To get started with the bimg library, you'll need to have the libvips library installed on your system. The installation

Competitor Comparisons

Fast, simple, scalable, Docker-ready HTTP microservice for high-level image processing

Pros of Imaginary

  • Imaginary is a high-performance HTTP microservice for image processing, built on top of the popular Go programming language.
  • It provides a simple and intuitive API for performing various image manipulation tasks, such as resizing, cropping, and format conversion.
  • Imaginary is designed to be highly scalable and can handle a large number of concurrent requests, making it suitable for high-traffic applications.

Cons of Imaginary

  • Imaginary is a standalone service, which means it requires additional setup and configuration compared to bimg, which is a library that can be directly integrated into your application.
  • The learning curve for Imaginary may be steeper than bimg, as developers need to understand how to set up and configure the service.
  • Imaginary may have a higher resource footprint than bimg, as it runs as a separate process.

Code Comparison

Here's a brief code comparison between bimg and Imaginary:

bimg (Go library):

img, err := bimg.Read("input.jpg")
if err != nil {
    // Handle error
}

newImg, err := img.Resize(200, 200)
if err != nil {
    // Handle error
}

err = bimg.Write("output.jpg", newImg)
if err != nil {
    // Handle error
}

Imaginary (HTTP microservice):

POST /resize HTTP/1.1
Host: localhost:8088
Content-Type: application/json

{
    "url": "http://example.com/input.jpg",
    "width": 200,
    "height": 200
}

Fast, dependency-free Go package to infer binary file types based on the magic numbers header signature

Pros of filetype

  • Lightweight and fast, with a small footprint and no external dependencies.
  • Supports a wide range of file types, including common image, audio, video, and document formats.
  • Provides a simple and intuitive API for detecting file types.

Cons of filetype

  • Limited to file type detection only, without any image processing capabilities.
  • May not be as comprehensive as some other file type detection libraries in terms of supported formats.
  • Lacks advanced features like image manipulation or conversion.

Code Comparison

filetype:

const filetype = require('filetype');
const buffer = fs.readFileSync('example.jpg');

const result = filetype(buffer);
console.log(result); // { ext: 'jpg', mime: 'image/jpeg' }

bimg:

const bimg = require('bimg');
const buffer = fs.readFileSync('example.jpg');

const image = bimg.open(buffer);
console.log(image.size()); // { width: 800, height: 600 }
2,115

HTTP traffic mocking and testing made easy in Go ༼ʘ̚ل͜ʘ̚༽

Pros of gock

  • Provides a simple and intuitive API for mocking HTTP requests and responses, making it easier to write testable code.
  • Supports a wide range of HTTP methods, headers, and query parameters, allowing for more comprehensive testing.
  • Includes support for dynamic response generation, enabling more realistic and complex mocking scenarios.

Cons of gock

  • May have a steeper learning curve compared to some other mocking libraries, especially for developers unfamiliar with the Go language.
  • Requires additional setup and configuration to integrate with existing test suites, which can add complexity to the testing process.
  • Might not provide the same level of flexibility and customization as some other mocking libraries, depending on the specific testing requirements.

Code Comparison

gock:

gock.New("https://api.example.com")
    .Get("/users")
    .Reply(200)
    .JSON(map[string]interface{}{
        "name": "John Doe",
        "email": "john@example.com",
    })

bimg:

img, err := bimg.Read("input.jpg")
if err != nil {
    return err
}

newImg, err := img.Resize(800, 600)
if err != nil {
    return err
}

err = bimg.Write("output.jpg", newImg)
if err != nil {
    return err
}

Plugin-driven, extensible HTTP client toolkit for Go

Pros of Gentleman

  • Gentleman is a lightweight and modular web framework for Go, providing a simple and flexible API for building web applications.
  • It offers a more opinionated and structured approach to web development compared to bimg, which is a more low-level image processing library.
  • Gentleman includes features like routing, middleware, and request/response handling out of the box, making it easier to build web applications quickly.

Cons of Gentleman

  • Gentleman may have a steeper learning curve compared to bimg, as it requires understanding the framework's conventions and patterns.
  • The additional features and abstractions provided by Gentleman may add some overhead and complexity compared to the more focused and lightweight bimg library.
  • The Gentleman project is less mature and has a smaller community compared to the more established bimg library.

Code Comparison

Gentleman (routing example):

r := gentleman.New()
r.Get("/", func(c *gentleman.Context) {
    c.Text(http.StatusOK, "Hello, World!")
})
r.Run(":8080")

bimg (image processing example):

img, err := bimg.Read("input.jpg")
if err != nil {
    panic(err)
}
newImg, err := img.Resize(200, 200)
if err != nil {
    panic(err)
}
err = bimg.Write("output.jpg", newImg)
if err != nil {
    panic(err)
}

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

bimg GoDoc Coverage Status License

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

bimg was designed to be a small and efficient library supporting common image operations such as crop, resize, rotate, zoom or watermark. It can read JPEG, PNG, WEBP natively, and optionally TIFF, PDF, GIF and SVG formats if libvips@8.3+ is compiled with proper library bindings. Lastly AVIF is supported as of libvips@8.9+. For AVIF support libheif needs to be compiled with an applicable AVIF en-/decoder.

bimg is able to output images as JPEG, PNG and WEBP formats, including transparent 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 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 API breaking changes.

Contents

Supported image operations

  • Resize
  • Enlarge
  • Crop (including smart crop support, libvips 8.5+)
  • Rotate (with auto-rotate based on EXIF orientation)
  • Flip (with auto-flip based on EXIF metadata)
  • Flop
  • Zoom
  • Thumbnail
  • Extract area
  • Watermark (using text or image)
  • Gaussian blur effect
  • Custom output color space (RGB, grayscale...)
  • Format conversion (with additional quality/compression settings)
  • EXIF metadata (size, alpha channel, profile, orientation...)
  • Trim (libvips 8.6+)

Prerequisites

  • libvips 8.3+ (8.8+ recommended)
  • C compatible compiler such as gcc 4.6+ or clang 3.0+
  • Go 1.3+

Note:

  • libvips v8.3+ is required for GIF, PDF and SVG support.
  • libvips v8.9+ is required for AVIF support. libheif compiled with a AVIF en-/decoder also needs to be present.

Installation

go get -u github.com/h2non/bimg

libvips

Follow libvips installation instructions:

https://libvips.github.io/libvips/install.html

Installation script

Note: install script is officially deprecated, it might not work as expected. We recommend following libvips install instructions.

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

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

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

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

The install script requires curl and pkg-config.

Performance

libvips is probably the fastest 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"
  "github.com/h2non/bimg"
)

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 == 800 && size.Height == 600 {
  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 preserving 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.

Authors

Credits

People who recurrently contributed to improve bimg in some way.

Thank you!

License

MIT - Tomas Aparicio

views

NPM DownloadsLast 30 Days