Image resizing in pure Go and SIMD

rez GoDoc Build Status

Package rez provides image resizing in pure Go and SIMD.

Download:

go get github.com/bamiaux/rez

Full documentation at http://godoc.org/github.com/bamiaux/rez


Package rez provides image resizing in pure Go and SIMD.

Featuring:

- YCbCr, RGBA, NRGBA & Gray resizes
- YCbCr Chroma subsample ratio conversions
- Optional interlaced-aware resizes
- Parallel resizes
- SIMD optimisations on AMD64

The easiest way to use it is:

err := Convert(output, input, NewBicubicFilter())

However, if you plan to convert video, where resize parameters are the same for multiple images, the best way is:

cfg, err := PrepareConversion(output, input)
converter, err := NewConverter(cfg, NewBicubicFilter())
for i := 0; i < N; i++ {
    err := converter.Convert(output[i], input[i])
}

Note that by default, images are resized in parallel with GOMAXPROCS slices. Best performance is obtained when GOMAXPROCS is at least equal to your CPU count.


Automatically generated by autoreadme on 2014.11.25

Owner
Comments
  • Crash when gonumprocs > number of scaled lines

    Crash when gonumprocs > number of scaled lines

    For a full demonstration, you can clone https://github.com/kjk/test_go_resize, run.sh, open http://localhost:5300 and click on bug 2 link.

    But basically the problem seems to be that if runtime.GOMAXPROCS() is > lines in the source (or destination ?) image, we'll get a crash:

    panic: runtime error: slice bounds out of range
    
    goroutine 24 [running]:
    runtime.panic(0x2e4ce0, 0x4cc6af)
        /usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/panic.c:279 +0xf5
    github.com/bamiaux/rez.scaleSlices(0xc208043360, 0x3b71d0, 0x1, 0x20, 0x8, 0x320, 0xa, 0x320, 0x320, 0xc20828a000, ...)
        /Users/kkowalczyk/src/go/src/github.com/bamiaux/rez/resize.go:131 +0x4db
    created by github.com/bamiaux/rez.(*context).Resize
        /Users/kkowalczyk/src/go/src/github.com/bamiaux/rez/resize.go:166 +0x384
    

    I discovered it running on 24 core machine but it can be simulated on any machine by e.g. calling runtime.GOMAXPROCS(32) and resizing 200x20 image => 100x10.

    It doesn't happen if threads are limited to 1.

    As an aside, maybe it would make sense to cap the number of gorutines to a smaller value than GOMAXPROCS() as there might be point of diminishing returns.

  • bad resize artifact on the right

    bad resize artifact on the right

    How to repro:

    • get the latest version of https://github.com/kjk/test_go_resize
    • ./run.sh
    • open http://localhost:5300
    • click on bug 3 link

    The problem is that the last vertical line in resized image has pretty bad color artifacts (mostly blue edge even though there's no blue color in the image)

    I've noticed it spot-checking resized images when comparing them to images resized with Image Magic.

    You have to spot the exact right dimensions for this to repro (which are modifiable by tweaking the url).

  • Add support for subsample ratio 4:1:0 and missing 4:1:1

    Add support for subsample ratio 4:1:0 and missing 4:1:1

    I was getting panics with an image with a subsample ratio that was not supported, this adds support for the two additional subsample ratios that are supported by Go.

  • Cannot build with Go >1.7

    Cannot build with Go >1.7

    Package can no longer be built with Go newer than Go 1.7:

    rez (master) ¶ go version
    go version devel +fc2e282 Thu Nov 3 14:27:24 2016 +0000 darwin/amd64
    rez (master) ¶ go build
    # github.com/bamiaux/rez
    duplicate zero_0
    asm: symbol zero_0 listed multiple times
    

    The reason for this seems to be that after golang/go@9741d83ceaf046e55077d68719cc2781cd96d5f1 asm is being called on multiple files at once, rather than on a single file.

  • unknown image format (PNG)

    unknown image format (PNG)

    The code:

    outputImage = image.NewRGBA(image.Rect(0, 0, targetWidth, targetHeight))
    err := rez.Convert(outputImage, img, rez.NewBilinearFilter())
    if err != nil {
      return errors.Wrap(err, "Could not convert PNG image") // unknown image format
    }
    

    The image: https://blokt.com/wp-content/uploads/2019/01/Screenshot-2019-01-11-at-15.21.20-610x409.png

    What is not compatible about the image, which is PNG format? Is this a bug in rez?

  • Fix broken headings in Markdown files

    Fix broken headings in Markdown files

    GitHub changed the way Markdown headings are parsed, so this change fixes it.

    See bryant1410/readmesfix for more information.

    Tackles bryant1410/readmesfix#1

  • Lift restrictions on YCbRb width/height

    Lift restrictions on YCbRb width/height

    rez refuses to resize some YCbRb images if it detects that its width/height is not compatible with its pixel format.

    While I understand that this might make the code simpler, when testing the code on lots of random jpeg images from the internet, rez refused to resize a lot of them.

    I worked-around the problem by converting them to RGBA, but it would be better if the library handled that internally.

  • Resizing some source sizes badly distorts images

    Resizing some source sizes badly distorts images

    Resizing sometimes badly distorts the image.

    For example, lena is 512x512 image. If you take the subset 402x400 of that image and resize to 200x200, it'll produce the following:

    resize rezult

    A simple way to reproduce this:

    • clone https://github.com/kjk/rez
    • cd testresize
    • run.sh
    • open localhost:5300 in your browser

    It shows how various subsets of the image gets resized. You'll notice that 4 out of 8 are distorted.

    For exact details of how I create those test images, read main.go, but it's exactly what you would expect.

  • crash when resizing a subimage

    crash when resizing a subimage

    Add the following code as new test e.g. subimage_test.go (https://github.com/kjk/rez/blob/master/subimage_test.go)

    package rez
    
    import (
        "image"
        "testing"
    )
    
    func TestResizeSubimage(t *testing.T) {
        src := readImage(t, "testdata/lenna.jpg")
        src2 := toRgb(src).(*image.RGBA)
        subR := image.Rect(10, 10, 340, 340)
        src3 := src2.SubImage(subR)
        dstRect := image.Rect(0, 0, 100, 100)
        dst := image.NewRGBA(dstRect)
        convert(t, dst, src3, false, NewBicubicFilter())
    }
    

    Run go test.

    The following crash will happen:

    --- FAIL: TestResizeSubimage (0.01 seconds)
    panic: runtime error: slice bounds out of range [recovered]
        panic: runtime error: slice bounds out of range
    
    goroutine 9262 [running]:
    runtime.panic(0x186200, 0x2999af)
        /usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/panic.c:279 +0xf5
    testing.func·006()
        /usr/local/Cellar/go/1.3/libexec/src/pkg/testing/testing.go:416 +0x176
    runtime.panic(0x186200, 0x2999af)
        /usr/local/Cellar/go/1.3/libexec/src/pkg/runtime/panic.c:248 +0x18d
    github.com/kjk/rez.getRgbPlane(0x208324040, 0x208310510, 0x0, 0x0, 0x0)
        /Users/kkowalczyk/src/go/src/github.com/kjk/rez/image.go:373 +0x1d6
    github.com/kjk/rez.inspectRgb(0x208324040, 0x2208301800, 0x208324040, 0x0, 0x0, 0x0)
        /Users/kkowalczyk/src/go/src/github.com/kjk/rez/image.go:384 +0xb2
    github.com/kjk/rez.inspect(0x2208301838, 0x208324040, 0x208324000, 0x22082f2900, 0x0, 0x0, 0x0, 0x0, 0x0)
        /Users/kkowalczyk/src/go/src/github.com/kjk/rez/image.go:314 +0xd5
    github.com/kjk/rez.PrepareConversion(0x2208301838, 0x208324640, 0x2208301838, 0x208324040, 0x24a4b, 0x0, 0x0)
        /Users/kkowalczyk/src/go/src/github.com/kjk/rez/image.go:432 +0x59
    github.com/kjk/rez.prepare(0x22082fe6d0, 0x208336090, 0x2208301838, 0x208324640, 0x2208301838, 0x208324040, 0x208324600, 0x22082fe618, 0x208324680, 0x0, ...)
        /Users/kkowalczyk/src/go/src/github.com/kjk/rez/resize_test.go:53 +0x68
    github.com/kjk/rez.convert(0x22082fe6d0, 0x208336090, 0x2208301838, 0x208324640, 0x2208301838, 0x208324040, 0x0, 0x22082fe618, 0x208324680)
        /Users/kkowalczyk/src/go/src/github.com/kjk/rez/resize_test.go:62 +0x97
    github.com/kjk/rez.TestResizeSubimage(0x208336090)
        /Users/kkowalczyk/src/go/src/github.com/kjk/rez/subimage_test.go:20 +0x3d0
    testing.tRunner(0x208336090, 0x2980b0)
        /usr/local/Cellar/go/1.3/libexec/src/pkg/testing/testing.go:422 +0x8b
    created by testing.RunTests
        /usr/local/Cellar/go/1.3/libexec/src/pkg/testing/testing.go:504 +0x8db
    

    In my code I did work-around this by copying the part I want to resize to a new image, but the additional allocation and copying slows things down.

    I guess the issue is with not handling image bounds that have origin point other than (0,0)

  • Don't use goroutines if cfg.Threads is 1

    Don't use goroutines if cfg.Threads is 1

    Currently rez will always start goroutines even if cfg.Threads is 1

    As a result if rez panics, it'll crash the whole app with it and there's no way to guard against it.

    Imagine e.g. web server that uses rez to resize images.

    If there was a way to tell rez not to use goroutines (e.g. by setting cfg.Threads to 1), one could at least do a recover around that panic and prevent the whole server from crashing.

  • Gamma handling?

    Gamma handling?

    24-bit RGB and YCbCr both use a gamma-adjusted scale for luminosity. Averaging of luminosity values must be done in the linear space in order to avoid corruption (shadows expanding/eating nearby pixels).

    Does this library address this? I don't see a reference to gamma adjustment, and the storage format appears to be 8-bit per channel, which can only contain gamma-adjusted data without loss, since you need 14 bits to store linearized values without truncation.

    The approach you took to SIMD acceleration here is impressive; I haven't seen an equivalent elsewhere.

Related tags
A lightning fast image processing and resizing library for Go

govips A lightning fast image processing and resizing library for Go This package wraps the core functionality of libvips image processing library by

Jan 8, 2023
An image resizing server written in Go
An image resizing server written in Go

picfit picfit is a reusable Go server to manipulate images (resize, thumbnail, etc.). It will act as a proxy on your storage engine and will be served

Dec 24, 2022
Image resizing for the Go programming language with common interpolation methods

This package is no longer being updated! Please look for alternatives if that bothers you. Resize Image resizing for the Go programming language with

Dec 14, 2021
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

Jan 5, 2022
Fast and secure standalone server for resizing and converting remote images

imgproxy imgproxy is a fast and secure standalone server for resizing and converting remote images. The main principles of imgproxy are simplicity, sp

Jan 1, 2023
Cloud function + website for resizing, cropping and bordering images for pragalicious.com

Cloud function + website for resizing, cropping and bordering images for pragalicious.com

Jan 23, 2022
darkroom - An image proxy with changeable storage backends and image processing engines with focus on speed and resiliency.
darkroom - An image proxy with changeable storage backends and image processing engines with focus on speed and resiliency.

Darkroom - Yet Another Image Proxy Introduction Darkroom combines the storage backend and the image processor and acts as an Image Proxy on your image

Dec 6, 2022
An API which allows you to upload an image and responds with the same image, stripped of EXIF data

strip-metadata This is an API which allows you to upload an image and responds with the same image, stripped of EXIF data. How to run You need to have

Nov 25, 2021
Image processing algorithms in pure Go
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

Jan 6, 2023
Pure Go encoder/decoder of the QOI image format

QOI - The “Quite OK Image” format for fast, lossless image compression package and small utilities in native Go, quite OK implementation See qoi.h for

Nov 12, 2022
Easily customizable Social image (or Open graph image) generator

fancycard Easily customizable Social image (or Open graph image) generator Built with Go, Gin, GoQuery and Chromedp Build & Run Simply, Clone this rep

Jan 14, 2022
Imgpreview - Tiny image previews for HTML while the original image is loading
Imgpreview - Tiny image previews for HTML while the original image is loading

imgpreview This is a Go program that generates tiny blurry previews for images t

May 22, 2022
Go package captcha implements generation and verification of image and audio CAPTCHAs.
Go package captcha implements generation and verification of image and audio CAPTCHAs.

Package captcha ⚠️ Warning: this captcha can be broken by advanced OCR captcha breaking algorithms. import "github.com/dchest/captcha" Package captch

Dec 30, 2022
Image processing library and rendering toolkit for Go.

blend Image processing library and rendering toolkit for Go. (WIP) Installation: This library is compatible with Go1. go get github.com/phrozen/blend

Nov 11, 2022
Go package for decoding and encoding TARGA image format

tga tga is a Go package for decoding and encoding TARGA image format. It supports RLE and raw TARGA images with 8/15/16/24/32 bits per pixel, monochro

Sep 26, 2022
Storage and image processing server written in Go
Storage and image processing server written in Go

Mort An S3-compatible image processing server written in Go. Still in active development. Features HTTP server Resize, Rotate, SmartCrop Convert (JPEG

Jan 7, 2023
A Go program that takes an image, uses pigo to detect a face, and creates a gif that zooms in on the face
A Go program that takes an image, uses pigo to detect a face, and creates a gif that zooms in on the face

ok-zoomer Every GIF is a gift. How it works face detection with esimov/pigo color quantization / dithering with esimov/colorquant image resizing with

Nov 27, 2022
An extensive, fast, and accurate command-line image dithering tool.
An extensive, fast, and accurate command-line image dithering tool.

didder is an extensive, fast, and accurate command-line image dithering tool. It is designed to work well for both power users as well as pipeline scripting. It is backed by my dithering library, and is unique in its correctness and variety of dithering algorithms.

Dec 31, 2022
A lightweight and easy to use tool for deflickering timelapse image sequences.
A lightweight and easy to use tool for deflickering timelapse image sequences.

Simple Deflicker A minimalist, lightning-fast and easy to use tool for deflickering image sequences such as timelapses. It's still in its early stages

Aug 12, 2022