Image resizing in pure Go and SIMD

Related tags

Images tools rez
Overview

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

Issues
  • 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.

    opened by kjk 6
  • 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).

    opened by kjk 3
  • 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.

    opened by jack0 2
  • 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/[email protected] asm is being called on multiple files at once, rather than on a single file.

    opened by artyom 2
  • 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?

    opened by ernsheong 1
  • 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

    opened by bryant1410 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.

    opened by kjk 1
  • 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.

    opened by kjk 1
  • 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)

    opened by kjk 1
  • 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.

    opened by kjk 0
  • 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.

    opened by lilith 1
Owner
Benoît Amiaux
Benoît Amiaux
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

David Byttow 731 Aug 8, 2022
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

Florent Messa 1.7k Jul 27, 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

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

imgproxy 6.4k Aug 9, 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
Cloud function + website for resizing, cropping and bordering images for pragalicious.com

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

Ard Scheirlynck 0 Jan 23, 2022
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

Gojek 194 Aug 3, 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

Cristina Simionescu 0 Nov 25, 2021
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.6k Jul 29, 2022
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

Xavier-Frédéric Moulet 56 Jun 3, 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

Youngbin Han 4 Jan 14, 2022
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

Dmitry Chestnykh 8 May 22, 2022
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

Dmitry Chestnykh 1.6k Jul 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

Guillermo Estrada 59 Dec 24, 2021
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

Sigrid Solveig Haflínudóttir 31 Jul 29, 2022
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

Marcin Kaciuba 460 Jul 19, 2022
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

Justin Birmingham 248 Jul 6, 2022
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.

makeworld 132 Jul 26, 2022
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

Lennart Demes 81 May 29, 2022