Compare various Image resize algorithms for the Go language

Overview

speedtest-resize

Compare various Image resize algorithms for the Go language

I am writing a web gallery called gonagall in Go (https://github.com/fawick/gonagall). For that, I need a efficient solution for scaling and resizing a lot of images (mostly JPGs) to generate thumbnails and bandwidth-friendly sized copies from high-resolution original photo files.

In this project I compare the speed of a few selected image resizing algorithms with each other as well as with ImageMagick and GraphicsMagick. The competitors are

Installation

To run the tests go get the source and compile/run it:

$ go get -u github.com/fawick/speedtest-resize -tags all
$ cd $GOPATH/src/speedtest-resize
$ go run main.go <jpg file folder>

Alternatively, call the go command (or the compiled binary) from the image folder without supplying a parameter

$ cd <jpg file folder>
$ go run $GOPATH/src/speedtest-resize/main.go

A the package requires different 3rdparty libraries to be installed, you can use build tags to control what libraries to use. The following build tags are available:

Tag Description
opencv Include lazywei/go-opencv in the tests.
imagick Include gographics/imagick in the tests.
vips Include DAddYE/vips in the tests.
fastjpeg Include camlistore/fastjpeg in the tests.
all An alias for opencv imagick fastjpeg vips.
nopure Don't include the Pure Golang packages
noexec Don't run the tests that execute other programs.

The default go get without any tags will try the packages that are pure go and the external programs but not use any non-Go library.

Benchmark

Im my test scenario all of these tools/packages are unleashed on a directory containing JPG photo files, all of which have a resolution of 5616x3744 pixels (aspect ratio 2:1, both landscape and portrait).

For each tool/package and for all files, the total time for loading the original file, scaling the image to a thumbnail of 150x100 pixels, and writing it to a new JPG file is measured. In the end, the total runtime for processing the 10 first files and the average time per file is printed for each tool/package.

The scenario is run on a Intel(R) Pentium(R) Dual T2390 @ 1.86GHz running Ubuntu 14.04. Here are the results:

Table Time (avg.) Size (avg.) Pure Go
vipsthumbnail 0.120s 0.065%
ImageMagick_thumbnail 0.326s 0.242%
vips 0.339s 0.100%
magickwand_box 1.148s 0.538%
ImageMagick_resize 2.316s 0.626%
rez_bilinear 2.913s 0.053% X
Nfnt_NearestNeighbor 3.498s 0.057% X
imaging_box 4.734s 0.057% X
gift_box 4.746s 0.057% X

Yet another scenario ran by lazywei, 2.5GHz Intel Core i5, Mac OS X 10.9.1:

Tables Average time per file
magickwand_box 155.371531ms
imaging_Box 463.459339ms
Nfnt_NearestNeighbor 1.436507946s
OpenCv 97.353041ms

Yet another scenario ran by bamiaux, 3.3GHz Intel Core i5, win 7:

Tables Average time per file
rez_bilinear 148ms
imaging_Box 243ms
Nfnt_NearestNeighbor 233ms

A new scenario ran by nono, 3.4GHz Intel Core i7, Ubuntu 16.10:

Table Time (file avg.) Size (file avg.) Pure Go
ImageMagick_thumbnail 0.057s 0.361%
vips 0.070s 0.260%
epeg 0.079s 0.207%
fastjpeg 0.082s 0.186%
opencv 0.110s 0.597%
vipsthumbnail 0.115s 0.441%
GraphicsMagick_thumbnail 0.172s 0.427%
magickwand_box 0.190s 0.575%
T-REZ 0.204s 0.323%
rez_bilinear 0.349s 0.140% X
x_image_draw 0.370s 0.160% X
imaging_box 0.439s 0.146% X
gift_box 0.440s 0.146% X
Nfnt_NearestNeighbor 0.447s 0.146% X
bild_resize 0.515s 0.206% X
ImageMagick_resize 0.568s 0.542%

So, what is to learn from that? While all of the currently existing pure-Go-language solutions do a pretty good job in generating good-looking thumbnails, they are much slower than the veteran dedicated image processing toolboxes. That is hardly surprising, given that both ImageMagick and GraphicsMagick have been around for decades and have been optimized to work as efficient as possible. Go and its image processing packages are still the new kids on the block, and while they work pretty neat for the occasional tweak of an image or two, I rather not use them as the default image processor in gonagall yet.

I was surprised to find that GraphicsMagick was slower than ImageMagick in my test scenario, as I expected it to be exactly the other way around with GraphicsMagick's fancy multi-processor algorithms.

While the imagick Wrapper is written in Go, it uses CGO bindings of the C MagickWand API. It outperforms the pure-Go approaches (five times faster than http://github.com/disintegration/imaging) but it still slower than calling ImageMagick in an external process. Of the above 1.13 seconds, only around 275 millisecs were used for resizing and saving an individual file, while over 850 ms were used by simply loading the file. I wonder how much optimization can still be done in the imagick loading routines.

Holy cow! vipsthumbnail is blazing fast.

Comments
  • Add VIPS

    Add VIPS

    http://www.vips.ecs.soton.ac.uk/index.php?title=VIPS http://www.vips.ecs.soton.ac.uk/index.php?title=Speed_and_Memory_Use

    Would be nice to have Go bindings for VIPS...

    Just for info: https://github.com/jcupitt/libvips/blob/master/tools/vipsthumbnail.c

    opened by matrixik 12
  • Some cmd output ideas

    Some cmd output ideas

    Some nice to have ideas:

    • Round time to third number after the decimal point.
    • Sort from fastest to slowest.
    • Use https://github.com/olekukonko/tablewriter for summary (with Github ready markdown)
    • Flag to only show summary
    • Show resized images summary file size
    opened by matrixik 4
  • Add go-opencv binding comparing.

    Add go-opencv binding comparing.

    Hi,

    I would like to add go-opencv into comparing candidate.

    I need some help with what to return in the resizing function. Therefore, I open this pull request and want to start the discussion. Thanks.

    Here is the benchmark I got for OpenCV

    magickwand_box took 343.293996ms, file average 49.041999ms
    imaging_Box took 973.294221ms, file average 139.042031ms
    Nfnt_NearestNeighbor took 3.231306082s, file average 461.615154ms
    OpenCv took 248.871481ms, file average 35.553068ms
    
    opened by lazywei 4
  • Differences between Exec and cgo Performance

    Differences between Exec and cgo Performance

    This is a great set of benchmarks, and I really appreciate the time & effort you've made to collect this information!

    My particular use-case involves resizing an image that is already in memory. Resizing this image with cgo bindings to native libraries would likely involve no disk access. In contrast, resizing it using a system command that is run with exec would involve writing the image to disk, execing the resize command of choice, and then reading the resulting image from disk. When disk access is factored in, performing the resize with a cgo binding to a native library might outperform running commands with exec.

    I'd like to see another set of benchmarks for exec that include the time to write & read the images from disk.

    opened by skidder 2
  • Add rez resizer

    Add rez resizer

    As it's not implementing nearest-neighbor, it's disadvantaged compare to some others. Yet, in my few tests, it seems to be faster than all other pure go solutions.

    It doesn't implement resizing rgb or rgb<->yuv, so it may fail on some inputs, but it's on my todo list.

    IMHO, you should really separate the jpeg encoding/decoding, if you really want to benchmark resize speeds.

    opened by bamiaux 2
  • Unrecognised import

    Unrecognised import

    Hi,

    I would like to run this test (because of nfnt/[email protected]) but go get is showing error:

    D:\Golibs>go get -u github.com/fawick/speedtest-resize
    package github.com/fawick/speedtest-resize
            imports github.com/disintegration/imaging
            imports github.com/gographics/imagick/imagick
            imports github.com/nfnt/resize
            imports resize: unrecognized import path "resize"
    

    Best regards, Dobrosław Żybort

    opened by matrixik 2
  • Benchmarks comparing native go and Cgo based libraries

    Benchmarks comparing native go and Cgo based libraries

    Hi @fawick,

    Thanks for this great repository. I have been exploring many image processing solutions for Go and I was considering using libraries like gmagick, imagick etc. But when I had compared these libraries with gift, gift seemed to outperform all of them. (Running ImageMagick and libvips in the command line was still the fastest, however).

    In your Readme.md, you've mentioned that the Cgo libraries outperform the native golang libraries. But you haven't included imagick or gmagick in any of the comparison tables. Could you share those results as well ?

    opened by tariq1890 1
  • Add some image encoders

    Add some image encoders

    Add some new contenders and make a run on my machine with all the image resizers.

    It looks like go has made some progress, but pure go encoders are still several times slower than the faster images encoder.

    opened by nono 1
Owner
Fabian Wickborn
Fabian Wickborn
Benchmarks of common basic operations for the Go language.

gocostmodel This package was inspired by Brian W. Kernighan and Rob Pike's book "The Practice of Programming" (Addison-Wesley, 1999). In Chapter 7 on

Martin Angers 60 Dec 23, 2022
Go micro-benchmarks for calculating the speed of language constructs

== About == Gospeed is a library of micro-benchmarks for Go which evolved from the GoLightly project. It's main utility is for understanding and reas

Eleanor McHugh 110 Sep 27, 2022
Compare - Functions that help compare and output test results

compare Functions that help compare and output test results. How to use Compare(

Dr. Takeyuki Ueda 0 Feb 16, 2022
go library for image programming (merge, crop, resize, watermark, animate, ease, transit)

Result Terminal Code mergi -t TT -i https://raw.githubusercontent.com/ashleymcnamara/gophers/master/Facepalm_Gopher.png -r "131 131" -i https://raw.gi

Noel Yahan 197 Jan 6, 2023
Content aware image resize library

Caire is a content aware image resize library based on Seam Carving for Content-Aware Image Resizing paper. How does it work An energy map (edge detec

Endre Simo 10.1k Jan 2, 2023
Asset storage and on-the-fly image resize

air - Asset & Image Resize Asset storage and on-the-fly image resize powered by libvips. Uploading an asset $ http -f POST http://127.0.0.1:1323/uploa

Alexandre Ferland 0 Feb 5, 2022
Image - This repository holds supplementary Go image librariesThis repository holds supplementary Go image libraries

Go Images This repository holds supplementary Go image libraries. Download/Insta

null 0 Jan 5, 2022
Golang string comparison and edit distance algorithms library, featuring : Levenshtein, LCS, Hamming, Damerau levenshtein (OSA and Adjacent transpositions algorithms), Jaro-Winkler, Cosine, etc...

Go-edlib : Edit distance and string comparison library Golang string comparison and edit distance algorithms library featuring : Levenshtein, LCS, Ham

Hugo Bollon 373 Dec 20, 2022
Golang string comparison and edit distance algorithms library, featuring : Levenshtein, LCS, Hamming, Damerau levenshtein (OSA and Adjacent transpositions algorithms), Jaro-Winkler, Cosine, etc...

Go-edlib : Edit distance and string comparison library Golang string comparison and edit distance algorithms library featuring : Levenshtein, LCS, Ham

Hugo Bollon 373 Dec 20, 2022
Go translations of the algorithms and clients in the textbook Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

Overview Go translations of the Java source code for the algorithms and clients in the textbook Algorithms, 4th Edition by Robert Sedgewick and Kevin

youngzy 175 Dec 13, 2022
Resize images and animated GIFs in Go

Lilliput relies on mature, high-performance C libraries to do most of the work of decompressing, resizing and compressing images. It aims to do as little memory allocation as possible and especially not to create garbage in Go. As a result, it is suitable for very high throughput image resizing services.

Discord 1.8k Jan 3, 2023
Automatically resize your ebs

ebs-autoresize Automatically resize your ebs. Table of Contents ebs-autoresize Table of Contents Installing Getting Started Resize Best practices Cont

Maksym Postument 47 Oct 16, 2022
Resize upladed images to s3 bucket with given sizes, and uploades new images back to bucket

Features Resize upladed images to s3 bucket with given sizes, and uploades new images back to bucket Environment Variables IMAGE_SIZES - formax 200x20

null 1 Feb 2, 2022
Algorithms for various integer sequences from the OEIS site.

OEIS The ongoing quest to program every sequence in the OEIS database (in Golang) Content sequences -- The folder containing the seq package, which co

null 0 Dec 23, 2021
Implementation of various data structures and algorithms in Go

GoDS (Go Data Structures) Implementation of various data structures and algorithms in Go. Data Structures Containers Lists ArrayList SinglyLinkedList

TopXeQ 0 Jan 25, 2022
Image processing algorithms in pure Go

bild A collection of parallel image processing algorithms in pure Go. The aim of this project is simplicity in use and development over absolute high

Anthony N. Simon 3.7k Jan 6, 2023
Converts an image file into various WebP images to use with img srcset

go-websizer Converts an image file into various WebP images to use with img srcset. Install $ go get github.com/pipe01/go-websizer Usage Usage of go-

Felipe Martínez 1 Oct 7, 2021
timestamp convert & compare tool. 时间戳转换与对比工具

ts timestamp convert & compare tool Install Shell Install support Linux & MacOS # binary will be $(go env GOPATH)/bin/ts $: curl -sfL https://raw.gith

JayL 16 Sep 26, 2022
Utility to compare files/directories with output in html. (like unix diff command)

#godiff A File/Directory diff-like comparison tool with HTML output. This program can be use to compare files and directories for differences. When co

null 42 Nov 4, 2022
Compare ANY markup documents.

Menu What is XML-Comp? Features Installing Running How this works? Comparing any kind of document Contributing To Do Using only the comparer package W

null 19 Oct 23, 2022