A Blurhash implementation in pure Go (Decode/Encode)

Overview

go-blurhash Build Status Go Report Card codecov GoDoc

go-blurhash is a pure Go implementation of the BlurHash algorithm, which is used by Mastodon an other Fediverse software to implement a swift way of preloading placeholder images as well as hiding sensitive media. Read more about it here.

tl;dr: BlurHash is a compact representation of a placeholder for an image.

This library allows generating the BlurHash of a given image, as well as reconstructing a blurred version with specified dimensions from a given BlurHash.

This library is based on the following reference implementations:

BlurHash is written by Dag Ågren / Wolt.

Before After
Image alt text "[email protected]_2%L%MIVD*9Goe-;WB"
Hash "[email protected]_2%L%MIVD*9Goe-;WB" alt text

Installation

From source

go get -u github.com/buckket/go-blurhash

Usage

go-blurhash exports three functions:

func blurhash.Encode(xComponents, yComponents int, rgba image.Image) (string, error)
func blurhash.Decode(hash string, width, height, punch int) (image.Image, error)
func blurhash.Components(hash string) (xComponents, yComponents int, err error)

Here’s a simple demonstration. Check pkg.go.dev for the full documentation.

package main

import (
	"fmt"
	"github.com/buckket/go-blurhash"
	"image/png"
	"os"
)

func main() {
	// Generate the BlurHash for a given image
	imageFile, _ := os.Open("test.png")
	loadedImage, err := png.Decode(imageFile)
	str, _ := blurhash.Encode(4, 3, loadedImage)
	if err != nil {
		// Handle errors
	}
	fmt.Printf("Hash: %s\n", str)

	// Generate an image for a given BlurHash
	// Width will be 300px and Height will be 500px
	// Punch specifies the contrasts and defaults to 1
	img, err := blurhash.Decode(str, 300, 500, 1)
	if err != nil {
		// Handle errors
	}
	f, _ := os.Create("test_blur.png")
	_ = png.Encode(f, img)
	
	// Get the x and y components used for encoding a given BlurHash
	x, y, err := blurhash.Components("[email protected]_2%L%MIVD*9Goe-;WB")
	if err != nil {
		// Handle errors
	}
	fmt.Printf("xComponents: %d, yComponents: %d", x, y)
}

Limitations

  • Presumably a bit slower than the C implementation (TODO: Benchmarks)

Notes

  • As mentioned here, it’s best to generate very small images (~32x32px) via BlurHash and scale them up to the desired dimensions afterwards for optimal performance.
  • Since #2 we diverted from the reference implementation by memorizing sRGBtoLinear values, thus increasing encoding speed at the cost of higher memory usage.
  • Starting with v1.1.0 the signature of blurhash.Encode() has changed slightly (see #3).

License

GNU GPLv3+

You might also like...
A Go library for an efficient implementation of a skip list: https://godoc.org/github.com/MauriceGit/skiplist
A Go library for an efficient implementation of a skip list: https://godoc.org/github.com/MauriceGit/skiplist

Fast Skiplist Implementation This Go-library implements a very fast and efficient Skiplist that can be used as direct substitute for a balanced tree o

A slice-based implementation of a stack. In Go!

Stackgo Stackgo is a slice-based implementation of a simple stack in Go. It uses a pre-alloc pagination strategy which adds little memory overhead to

A Left-Leaning Red-Black (LLRB) implementation of balanced binary search trees for Google Go

GoLLRB GoLLRB is a Left-Leaning Red-Black (LLRB) implementation of 2-3 balanced binary search trees in Go Language. Overview As of this writing and to

Golang implementation of Radix trees

go-radix Provides the radix package that implements a radix tree. The package only provides a single Tree implementation, optimized for sparse nodes.

gtreap is an immutable treap implementation in the Go Language

gtreap gtreap is an immutable treap implementation in the Go Language Overview gtreap implements an immutable treap data structure in golang. By treap

An yet-another red-black tree implementation, with a C++ STL-like API.

A red-black tree with an API similar to C++ STL's. INSTALLATION go get github.com/yasushi-saito/rbtree EXAMPLE More examples can be fou

A simple Bloom Filter implementation in Go

This is a simple Bloom filter implementation written in Go. For the theory behind Bloom filters, read http://en.wikipedia.org/wiki/Bloom_filter This

HyperLogLog and HyperLogLog++ implementation in Go/Golang.
HyperLogLog and HyperLogLog++ implementation in Go/Golang.

HyperLogLog and HyperLogLog++ Implements the HyperLogLog and HyperLogLog++ algorithms. HyperLogLog paper: http://algo.inria.fr/flajolet/Publications/F

A go implementation of Verkle trees

go-verkle A very experimental implementation of Verkle trees. When production-ready, the code is to be split between go-kzg and go-ethereum. Notes Nod

Comments
  • Pointer to image.Image interface

    Pointer to image.Image interface

    This library has the Encode API take in a pointer to image.Image (*image.Image) instead of either the interface itself (which has an underlying value of a pointer) or a concrete struct such as *image.NRGBA. This is usually a bad idea.

    The lines that use this "pointer to interface" seem to only dereference the interface and not change it:

    https://github.com/buckket/go-blurhash/blob/master/encode.go#L110-L111

    height := (*rgba).Bounds().Max.Y
    width := (*rgba).Bounds().Max.X
    

    https://github.com/buckket/go-blurhash/blob/master/encode.go#L131

    rt, gt, bt, _ := (*rgba).At(x, y).RGBA()
    
    enhancement 
    opened by diamondburned 1
Owner
buckket
buckket
Go implementation of Count-Min-Log

Count-Min-Log Count-Min-Log sketch: Approximately counting with approximate counters - Guillaume Pitel & Geoffroy Fouquier TL;DR: Count-Min-Log Sketch

Seif Lotfy 58 Sep 26, 2022
A Go implementation of the Elias-Fano encoding

go-ef A Go implementation of the Elias-Fano encoding Example package main import ( "fmt" "github.com/amallia/go-ef" "os" ) func main() {

Antonio Mallia 27 Nov 23, 2022
Set is a useful collection but there is no built-in implementation in Go lang.

goset Set is a useful collection but there is no built-in implementation in Go lang. Why? The only one pkg which provides set operations now is golang

zoumo 50 Sep 26, 2022
A skip list implementation in Go

About This is a library implementing skip lists for the Go programming language (http://golang.org/). Skip lists are a data structure that can be used

Ric (Ryszard) Szopa 236 Sep 21, 2022
Go implementation of C++ STL iterators and algorithms.

iter Go implementation of C++ STL iterators and algorithms. Less hand-written loops, more expressive code. README translations: 简体中文 Motivation Althou

disksing 172 Nov 16, 2022
Go implementation to calculate Levenshtein Distance.

levenshtein Go package to calculate the Levenshtein Distance The library is fully capable of working with non-ascii strings. But the strings are not n

Agniva De Sarker 251 Nov 15, 2022
A Merkle Tree implementation written in Go.

Merkle Tree in Golang An implementation of a Merkle Tree written in Go. A Merkle Tree is a hash tree that provides an efficient way to verify the cont

Cameron Bergoon 399 Nov 26, 2022
A prefix tree implementation in go

Trie (Prefix tree) This library is compatible with Go 1.11+ Please refer to CHANGELOG.md if you encounter breaking changes. Motivation Introduction Us

Viant, Inc 31 Nov 3, 2022
Package ring provides a high performance and thread safe Go implementation of a bloom filter.

ring - high performance bloom filter Package ring provides a high performance and thread safe Go implementation of a bloom filter. Usage Please see th

Tanner Ryan 130 Nov 20, 2022
A simple Set data structure implementation in Go (Golang) using LinkedHashMap.

Set Set is a simple Set data structure implementation in Go (Golang) using LinkedHashMap. This library allow you to get a set of int64 or string witho

Studio Sol Comunicação Digital Ltda 22 Sep 26, 2022