Rebol3 Code Examplex
Color quantization (Median cut)
Reduce an image’s palette using median-cut clustering.
Rebol [
title: "Rosetta code: Color quantization (Median cut)"
file: %Color_quantization-median_cut.r3
url: https://rosettacode.org/wiki/Color_quantization
]
median-cut: function [
"Reduces image to N colors using the median cut algorithm"
img [image! file! url!] "Source image to quantize (modified)"
n-colors [integer!] "Number of requested colors"
][
unless image? img [img: load img]
colors: make block! n-colors
;; Build a flat bucket block [clr1 idx1 clr2 idx2 ...]
;; where each clr is a tuple! and idx is the pixel's position in the image
bucket: make block! img/size/x * img/size/y
idx: 1 foreach clr img [ repend bucket [clr ++ idx] ]
;; Pre-sort once — all buckets remain sorted after every split
sort/skip bucket 2
;; Start with one bucket containing all pixels
buckets: reduce [bucket]
;; Keep splitting until we have enough buckets for the requested color count
while [n-colors > length? buckets] [
;; Take the first bucket (always the largest due to append order)
bucket: take buckets
;; Split at the upper median to ensure the most even division of pairs
med: 2 * round/ceiling (length? bucket) / 2 / 2
;; Append the upper median and the remainder back as two new buckets
append/only buckets take/part bucket med
append/only buckets bucket
]
;; Quantize each bucket
foreach bucket buckets [
;; Averages all colors in a bucket
r-sum: 0 g-sum: 0 b-sum: 0
foreach [clr idx] bucket [
r-sum: r-sum + clr/1
g-sum: g-sum + clr/2
b-sum: b-sum + clr/3
]
n: 0.5 * length? bucket ;; number of colors in the bucket
mean-color: to tuple! reduce [
r-sum / n
g-sum / n
b-sum / n
]
;; Write the mean color back to every pixel in this bucket
foreach [clr idx] bucket [ img/:idx: mean-color ]
;; Keep the mean color
append colors mean-color
]
;; Return image and colors
reduce [img colors]
]
;; Download the original image if does not exists.
unless exists? %Quantum_frog.png [
write %quantum_frog.png
read https://static.wikitide.net/rosettacodewiki/3/3f/Quantum_frog.png
]
foreach [colors output-name] [
16 %Quantum_frog-16-colors.png
3 %Quantum_frog-3-colors.png
][
;; Quantize to N colors
time: delta-time [
set [img colors] median-cut %Quantum_frog.png colors
]
print ["Time to compute:" time]
;; Display all used colors
print ["The" length? colors "colors:"]
probe new-line/all colors true
save output-name img ;; Save the result
browse output-name ;; Display the image in a browser
]