Skip to content

Instantly share code, notes, and snippets.

@azaek
Created September 8, 2022 15:57
Show Gist options
  • Save azaek/731a76bf41dd45e6f66f8d06a53100bd to your computer and use it in GitHub Desktop.
Save azaek/731a76bf41dd45e6f66f8d06a53100bd to your computer and use it in GitHub Desktop.
React Hook get image colors
import { useState, useEffect } from "react";
const useImageColor = (img: HTMLImageElement) => {
const [color, setColor] = useState<any>(null);
useEffect(() => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
function rgbToHex(r: any, g: any, b: any) {
r = r.toString(16);
g = g.toString(16);
b = b.toString(16);
if (r.length == 1)
r = "0" + r;
if (g.length == 1)
g = "0" + g;
if (b.length == 1)
b = "0" + b;
return r + g + b;
}
function hexToRgb(hex: string) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : {
r: 0,
g: 0,
b: 0
};
}
function getCustomHex(r: any, g: any, b: any) {
console.log(r, g, b);
r /= 255;
g /= 255;
b /= 255;
const l = Math.max(r, g, b);
const s = l - Math.min(r, g, b);
const h = s
? l === r
? (g - b) / s
: l === g
? 2 + (b - r) / s
: 4 + (r - g) / s
: 0;
let nL = 90 //(100 * (2 * l - s)) / 2; // increased the lightness to get bright color
let nS = 100 * (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0);
let nH = 60 * h < 0 ? 60 * h + 360 : 60 * h;
nS /= 100;
nL /= 100;
const k = (n:any)=> (n + nH/30) % 12;
const a = nS * Math.min(nL, 1 - nL);
const f = (n:any) => nL - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
let nR = 255 * f(0);
let nG = 255 * f(8);
let nB = 255 * f(4);
console.log(nR, nG, nB);
return rgbToHex(parseInt(nR+""), parseInt(nG+""), parseInt(nB+""));
}
if (ctx && img) {
canvas.width = img.width;
canvas.height = img.height;
ctx.fillStyle = "white";
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, img.width, img.height);
// const imageData = ctx.getImageData(img.width / 2, 100, 1, 1);
// const data = imageData.data;
var col, colors: any = {};
var pixels, r, g, b, a;
// r = g = b = a = 0;
pixels = ctx.getImageData(0, 0, canvas.width, canvas.height * 0.2);
for (var i = 0, data = pixels.data; i < data.length; i += 4) {
r = data[i];
g = data[i + 1];
b = data[i + 2];
a = data[i + 3]; // alpha
// skip pixels >50% transparent
if (a < (255 / 2))
continue;
col = rgbToHex(r, g, b);
if (!colors[col])
colors[col] = 0;
colors[col]++;
}
const cArr : any[] = [];
var cs = Object.keys(colors);
var occ: number[] = Object.values(colors);
for (var i = 0; i < cs.length; i++) {
cArr.push({
color: cs[i],
occ: occ[i]
});
}
cArr.sort((a, b) => b.occ - a.occ);
let rgb = hexToRgb(cArr[2]?.color);
setColor("#"+ getCustomHex(rgb.r, rgb.g, rgb.b));
// const r = data[0];
// const g = data[1];
// const b = data[2];
// const a = data[3];
// const rgba = `rgb(${r}, ${g}, ${b})`;
// setColor(rgba);
}
}, [img]);
return color;
}
export default useImageColor;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment