Finding An Image's Dominant Color In Go
Finding An Image’s Dominant Color In Go
I recently had a requirement: automatically choose a page background color based on the dominant color of an image. Since the backend service was written in Go, I first looked at whether this could be done directly in Go.
After trying a few options, github.com/cenkalti/dominantcolor turned out to be the simplest and most suitable choice.
Here is a minimal example:
package main
import (
"bytes"
"fmt"
"image"
"image/jpeg"
"io"
"io/ioutil"
"net/http"
"github.com/cenkalti/dominantcolor"
)
func GetImageByUrl(url string) (img image.Image, err error) {
res, err := http.Get(url)
if err != nil {
return
}
defer func(body io.ReadCloser) {
_ = body.Close()
}(res.Body)
data, err := ioutil.ReadAll(res.Body)
if err != nil {
return
}
reader := bytes.NewReader(data)
img, err = jpeg.Decode(reader)
return
}
func FindDomiantColor(url string) (c string, err error) {
img, err := GetImageByUrl(url)
if err != nil {
return
}
return dominantcolor.Hex(dominantcolor.Find(img)), nil
}
func main() {
fmt.Println(FindDomiantColor("https://n.sinaimg.cn/news/transform/310/w710h400/20220701/8cd8-e663ace484b6d8dcc548a18691e30c0a.jpg"))
}
This example downloads an image, decodes it, and prints the dominant color. In my test, the result was #544F4C.

The result matched the image reasonably well. But for images with several large color blocks, choosing only one dominant color may not be enough:

If the system must pick one color automatically, there is no perfect answer. If the user can intervene, there are more options, because dominantcolor can also output multiple candidate colors.
The official demo program is useful for this:

The demo is also written in Go, based on dominantcolor and fyne.io. It is easy to try:
go install github.com/stuartmscott/dominantcolor
$GOPATH/dominantcolor

The desktop app lets you select a local image and calculates the six most frequently used color blocks. It can also run on Windows, but because it needs GL-related dependencies and may require GCC, I did not try the Windows path. The screenshot above was taken under WSL. Modern WSL can run graphical Linux applications, which is convenient, although the performance does not look especially strong.
According to the library documentation, the algorithm uses K-means clustering in RGBA color space and is derived from Chromium source code:
- https://github.com/adobe/chromium/blob/master/ui/gfx/color_analysis.h
- https://github.com/adobe/chromium/blob/master/ui/gfx/color_analysis.cc
Follow ZiCode on WeChat
If this post was useful, you can follow later updates on WeChat as well.
X / Twitter
Follow @ax2_zicode
Faster technical notes, short thoughts, and new-post alerts are posted on X.