imagor

Fast, secure image processing server and Go library, using libvips

APACHE-2.0 License

Stars
3.2K
Committers
22

Bot releases are hidden (Show)

imagor - v1.2.2

Published by cshum about 2 years ago

What's Changed

New Contributors

Full Changelog: https://github.com/cshum/imagor/compare/v1.2.0...v1.2.2

imagor - v1.2.0

Published by cshum about 2 years ago

Improved Memory Allocation

imagor v1.2.0 improved average memory usage over 30% compare with v1.1.5. This is done by revamping the streaming mechanisms to be more efficient and less memory allocations and copy operations. By doing so imagor introduced 2 reusable Go packages seekstream and fanoutreader that incorporated into imagor.Blob mechanisms:

seekstream

seekstream allows seeking on non-seekable io.ReadCloser source by buffering read data using memory or temp file.

https://pkg.go.dev/github.com/cshum/imagor/seekstream

import  "github.com/cshum/imagor/seekstream"
... 
var source io.ReadCloser // non-seekable
var buffer seekstream.Buffer // memory or temp file buffer
... 
var rs io.ReadSeekCloser = seekstream.New(source, buffer) // seekable

fanoutreader

fanoutreader allows fanout arbitrary number of reader streams concurrently from one data source with known total size, using channel and memory buffer.

https://github.com/cshum/imagor/tree/master/fanoutreader

import  "github.com/cshum/imagor/fanoutreader"
... 
// http source with known size via Content-Length header
resp, _ := http.DefaultClient.Get("https://raw.githubusercontent.com/cshum/imagor/master/testdata/gopher.png")
size, _ := strconv.Atoi(resp.Header.Get("Content-Length"))
fanout := fanoutreader.New(resp.Body, size) // create fanout from single reader source

var wg sync.WaitGroup
for i := 0; i < 10; i++ {
	wg.Add(1)
	go func(i int) {
		reader := fanout.NewReader() // spawn new reader
		defer reader.Close()
		file, _ := os.Create(fmt.Sprintf("gopher-%d.png", i))
		defer file.Close()
		_, _ = io.Copy(file, reader) // read concurrently alongside other readers
		wg.Done()
	}(i)
}
wg.Wait()

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v1.1.9...v1.2.0

imagor - v1.1.9

Published by cshum about 2 years ago

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v1.1.6...v1.1.9

imagor - v1.1.6

Published by cshum about 2 years ago

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v1.1.5...v1.1.6

imagor - v1.1.5

Published by cshum about 2 years ago

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v1.1.4...v1.1.5

imagor - v1.1.4

Published by cshum about 2 years ago

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v1.1.3...v1.1.4

imagor - v1.1.3

Published by cshum about 2 years ago

Stability Release

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v1.1.0...v1.1.3

imagor - v1.1.0

Published by cshum about 2 years ago

Introducing imagorvideo

imagorvideo is a new initiative that brings video thumbnail capability with ffmpeg, built on the foundations of imagor v1.1.

Imagorvideo uses ffmpeg C bindings that extracts image thumbnail from video by attempting to select the best frame, then forwards to libvips to perform all existing image operations supported by imagor.

Check it out at https://github.com/cshum/imagorvideo

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v1.0.3...v1.1.0

imagor - v1.0.3

Published by cshum about 2 years ago

What's Changed

New Contributors

Full Changelog: https://github.com/cshum/imagor/compare/v1.0.2...v1.0.3

imagor - v1.0.2

Published by cshum about 2 years ago

Text Label Filter

label(text, x, y, size, color[, alpha[, font]])

Adds a text label to the image. It can be positioned inside the image with the alignment specified, color and transparency support:

  • text text label, also support url encoded text.
  • x horizontal position that the text label will be in:
    • Positive number indicate position from the left, negative number from the right.
    • Number followed by a p e.g. 20p means calculating the value from the image width as percentage
    • left,right,center align left, right or centered respectively
  • y vertical position that the text label will be in:
    • Positive number indicate position from the top, negative number from the bottom.
    • Number followed by a p e.g. 20p means calculating the value from the image height as percentage
    • top,bottom,center vertical align top, bottom or centered respectively
  • size - text label font size
  • color - color name or hexadecimal rgb expression without the “#” character
  • alpha - text label transparency, a number between 0 (fully opaque) and 100 (fully transparent).
  • font - text label font type

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v1.0.1...v1.0.2

imagor - v1.0.1

Published by cshum about 2 years ago

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v1.0.0...v1.0.1

imagor - v1.0.0

Published by cshum about 2 years ago

Streaming libvips

At the moment, all existing popular Go + libvips image applications (imgproxy, imaginary, bimg etc) bridge libvips through buffer. While these are all good with normal web images, the latency and memory overhead can be noticeable when working through large, raw images, as they are all loading the whole image buffer in memory, one step at a time.

Imagor v1 fully revamped the libvips binding, now implemented its streaming capability that enables parallel processing across Loader, Storage and Processor. This greatly increases network throughput especially with network sources like HTTPs, S3, GCS, by giving the ability to overlap processing pipelines.

Metadata and Exif

Imagor now provides metadata endpoint that extracts image info such as image format, dimensions and Exif metadata. With streaming in place, same goes for image Exif metadata. Imagor can try to retrieve data just enough to extract the header, without reading and processing the whole image in memory.

To use the metadata endpoint, add /meta right after the URL signature hash before the image operations. Example:

http://localhost:8000/unsafe/meta/fit-in/50x50/raw.githubusercontent.com/cshum/imagor/master/testdata/Canon_40D.jpg
{
  "format": "jpeg",
  "content_type": "image/jpeg",
  "width": 50,
  "height": 34,
  "orientation": 1,
  "pages": 1,
  "exif": {
    "ApertureValue": "368640/65536",
    "ColorSpace": 1,
    "ComponentsConfiguration": "Y Cb Cr -",
    "Compression": 6,
    "DateTime": "2008:07:31 10:38:11",
    // ...
    "WhiteBalance": 0,
    "XResolution": "72/1",
    "YCbCrPositioning": 2,
    "YResolution": "72/1"
  }
}

What's Changed

  • feat(vips): revamp libvips binding by @cshum
  • feat(vips): vips load image directly from file by @cshum
  • build(docker): fix docker build steps by @cshum
  • feat(vips): true streaming for libvips by @cshum
  • refactor(vips): context gc tracking by @cshum
  • build(deps): bump github.com/peterbourgon/ff/v3 from 3.2.0-rc.1 to 3.3.0 by @dependabot
  • build(deps): bump github.com/aws/aws-sdk-go from 1.44.66 to 1.44.70 by @dependabot
  • refactor(imagor): improve processor and storage concurrency by @cshum
  • feat(vips): exif metadata support by @cshum
  • refactor: simplify metadata architecture by @cshum

Full Changelog: https://github.com/cshum/imagor/compare/v0.9.13...v1.0.0

imagor - v0.9.13

Published by cshum about 2 years ago

New Config Options

  -imagor-process-concurrency int
        Maximum number of image process to be executed simultaneously. Requests that exceed this limit are put in the queue. Set -1 for no limit (default -1)
  -imagor-process-queue-size int
        Maximum number of image process that can be put in the queue. Requests that exceed this limit are rejected with HTTP status 429. Set -1 for no limit (default -1)

What's Changed

  • fix(imagor): client canceled request handling by @cshum
  • build(actions): ghcr delete untagged images by @cshum
  • refactor(filestorage): cleanup redundant logic by @cshum
  • feat(imagor): process-queue-size by @cshum

Full Changelog: https://github.com/cshum/imagor/compare/v0.9.12...v0.9.13

imagor - v0.9.12

Published by cshum about 2 years ago

Image Bombs Prevention

Imagor now checks the image type and its resolution before the actual processing happens. The image processing will be rejected if the dimensions are too big (you can set the max allowed image resolution using -vips-max-resolution), which protects from so called "image bombs”.

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v0.9.11...v0.9.12

imagor - v0.9.11

Published by cshum about 2 years ago

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v0.9.10...v0.9.11

imagor - v0.9.10

Published by cshum about 2 years ago

Revamp Config Initialization

When using Imagor as a Go package, it is now much easier to reuse and enable/disable components being loaded. For instance the main function now looks like this:

package main

import (
	"github.com/cshum/imagor/config"
	"github.com/cshum/imagor/config/awsconfig"
	"github.com/cshum/imagor/config/gcloudconfig"
	"github.com/cshum/imagor/config/vipsconfig"
	"os"
)

func main() {
	var server = config.CreateServer(
		os.Args[1:],
		vipsconfig.WithVips, // enable libvips Processor config
		awsconfig.WithAWS, // enable AWS Loader, Storage, Result Storage config
		gcloudconfig.WithGCloud // enable GCS Loader, Storage, Result Storage config
	)
	if server != nil {
		server.Run()
	}
}

Better PNG Performance

Added libspng to Docker build. When possible, libvips 8.13 will use the library for PNG write as well as PNG read. This can produce a useful increase in PNG speed.

What's Changed

Full Changelog: https://github.com/cshum/imagor/compare/v0.9.8...v0.9.10

imagor - v0.9.8

Published by cshum about 2 years ago

libvips 8.13

Imagor now with upgraded libvips to v8.13:
https://www.libvips.org/2022/05/28/What's-new-in-8.13.html

Much better GIF performance

The most noticeable improvements is GIF handling, which has been reworked again in libvips 8.13, producing smaller files with much lower CPU and memory load.

Compared to imagemagick6, libvips is around 10x faster, needs 4x less memory, makes GIFs which are 20% smaller, and produces higher quality output.

What's Changed

New Contributors

Full Changelog: https://github.com/cshum/imagor/compare/v0.9.7...v0.9.8

imagor - v0.9.7

Published by cshum over 2 years ago

Custom HMAC Signer Support

Imagor uses SHA1 HMAC signer by default, the same one used by Thumbor. However, SHA1 is not considered cryptographically secure. If that is a concern it is possible to configure different HMAC signing method and truncate length. Imagor supports sha1, sha256, sha512 signer type:

IMAGOR_SIGNER_TYPE=sha256
IMAGOR_SIGNER_TRUNCATE=32

An example URL signature generator in Node.js:

var hmacSHA256 = require("crypto-js/hmac-sha256")
var Base64 = require("crypto-js/enc-base64")

function sign(path, secret) {
  var hash = hmacSHA256(path, secret)
  hash = Base64.stringify(hash).slice(0, 32).replace(/\+/g, '-').replace(/\//g, '_')
  return hash + '/' + path
}

What's Changed

  • feat(imagor): imagor-signer-type by @cshum in https://github.com/cshum/imagor/pull/67
  • fix(imagor): fix fanout reader upstream error and premature close handling
  • fix(imagor): ErrPass handling
  • refactor(imagor): fanout reader lazy init
  • build: docker go 1.18.3

Full Changelog: https://github.com/cshum/imagor/compare/v0.9.6...v0.9.7

imagor - v0.9.6

Published by cshum over 2 years ago

What's Changed

  • fix(imagor): should not write empty bytes if blob originated from storage
  • refactor(imagor): loader storage sequence enhancement
  • feat(imagor): blob.Sniff() method
  • feat: storage.Del interface and implementation for filestorage, s3storage, gcloudstorage
  • refactor(imagor): imagor.ErrInvalid

Full Changelog: https://github.com/cshum/imagor/compare/v0.9.3...v0.9.6

imagor - v0.9.3

Published by cshum over 2 years ago

Improved Throughput with imagor.Blob

Imagor v0.9 introduced imagor.Blob as the mechanism for bytes transfer and content type sniffing, which supports spawning multiple concurrent Reader stream from a single source. This greatly improved the throughput across Loader, Storage, Result Storage and HTTP response.

Base Params Support

Using -imagor-base-pararms You can now configure predefined endpoint params that applies to all resulting images.
For example, a watermark for every generated images:

docker run -p 8000:8000 shumc/imagor:0.9.3 -imagor-unsafe -imagor-base-params 'filters:watermark(raw.githubusercontent.com/cshum/imagor/master/testdata/gopher-front.png,-15,-15,20,30,30)'

Try out the following URLs:

http://localhost:8000/unsafe/fit-in/200x200/filters:fill(white)/raw.githubusercontent.com/cshum/imagor/master/testdata/gopher.png
http://localhost:8000/unsafe/fit-in/200x200/filters:fill(yellow)/raw.githubusercontent.com/cshum/imagor/master/testdata/nyan-cat.gif

gopher nyan-cat

New Config Options

  -imagor-base-params string
        Imagor endpoint base params that applies to all resulting images e.g. fitlers:watermark(example.jpg)
  -imagor-disable-params-endpoint
        Imagor disable /params endpoint
  -imagor-disable-error-body
        Imagor disable response body on error

What's Changed

  • feat(imagor): metadata from result storage by @cshum in https://github.com/cshum/imagor/pull/65
  • feat(imagor): io.Reader, io.Writer stream based Blob container by @cshum in https://github.com/cshum/imagor/pull/66
  • feat(imagor): -imagor-disable-error-body
  • feat(imagor): -imagor-disable-params-endpoint
  • feat(imagor): base endpoint params support with -imagor-base-params
  • fix(vips): fix image ref gc
  • fix(imagor): fix blob error expansion

Full Changelog: https://github.com/cshum/imagor/compare/v0.8.29...v0.9.3