Skip to content

Instantly share code, notes, and snippets.

@todbot
Last active March 10, 2024 00:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save todbot/c47e7f1c92caee1c9c1569bc4d08ca52 to your computer and use it in GitHub Desktop.
Save todbot/c47e7f1c92caee1c9c1569bc4d08ca52 to your computer and use it in GitHub Desktop.
Compute average color of a JPEG image in CircuitPython
# Compute the average (median or mean) color of a JPEG using ulab.numpy
# 9 Mar 2024 - @todbot / Tod Kurt
# Note: test images are included as comment below, max tested resolution 256x192
import ulab.numpy as np
import displayio
import jpegio
def rgb565_to_rgb888(v, swapped=True):
"""Convert RGB565 (normal or swapped) to RGB888 tuple"""
if swapped:
v = ((v & 0xff) << 8) | ((v >> 8) & 0xff)
r8 = (v >> 11) << 3
g8 = ((v >> 5) << 2) & 0xff
b8 = (v << 3) & 0xff
return r8, g8, b8
def bitmap565_to_nparray888(bitmap):
"""Turn a Bitmap in RGB565_SWAPPED colorspace to RGB888 ndarray"""
w,h = bitmap.width, bitmap.height
a = np.array(np.zeros((w*h,3)), dtype=np.int16)
for y in range(h):
for x in range(w):
a[y*w+x] = rgb565_to_rgb888(bitmap[x,y])
return a
def average_color_for_jpeg(jpeg_fname):
"""For a given JPG file, determine most common color
Returns both median (most common) and average as two RGB tuples"""
decoder = jpegio.JpegDecoder()
width, height = decoder.open(jpeg_fname)
bitmap = displayio.Bitmap(width, height, 65535) # RGB565_SWAPPED is 16-bit
decoder.decode(bitmap)
ndbitmap = bitmap565_to_nparray888(bitmap)
med = np.median(ndbitmap, axis=0)
avg = np.mean(ndbitmap, axis=0)
rgb_median = int(med[0]),int(med[1]),int(med[2])
rgb_mean = int(avg[0]),int(avg[1]),int(avg[2])
return (rgb_median, rgb_mean)
jpeg_fnames = (
"/imgs/test1.jpg",
"/imgs/Mixed-forest-256.jpg",
"imgs/Adirondacks_in_May_2008-256.jpg",
)
for jpeg_fname in jpeg_fnames:
print("jpeg file:", jpeg_fname)
rgb_median, rgb_avg = average_color_for_jpeg(jpeg_fname)
print("median color: %02X%02X%02X" % rgb_median)
print("average color: %02X%02X%02X" % rgb_avg)
@todbot
Copy link
Author

todbot commented Mar 9, 2024

The test images used:
Adirondacks_in_May_2008-256
Mixed-forest-256
test1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment