Created
October 28, 2016 20:26
-
-
Save redzumi/66f450f1e4540ca7ca037ca43c7e7f4a to your computer and use it in GitHub Desktop.
Average color of image.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default class Colourz { | |
constructor() { | |
} | |
//TODO async/await | |
getAverageColorRGB(url, callback) { | |
try { | |
this.getImageBase64(url, (err, imgBase64) => { | |
if(err) return callback(err); | |
//new image | |
let img = new Image(); | |
img.src = imgBase64; | |
//gettin' color | |
let rgb = this.getAverageRGB(img); | |
if(!rgb) return callback(new Error('Cant get average color')); | |
return callback(null, rgb); | |
}); | |
} catch (ex) { | |
callback(ex); | |
} | |
} | |
getAverageColorHex(url, callback) { | |
this.getAverageColorRGB(url, (err, colorRGB) => { | |
if(err) return callback(err); | |
callback(null, this.rgbToHex(colorRGB.r + 20, colorRGB.g + 20, colorRGB.b + 20)); | |
}); | |
} | |
rgbToHex(r, g, b) { | |
const componentToHex = (c) => { | |
let hex = c.toString(16); | |
return hex.length == 1 ? "0" + hex : hex; | |
}; | |
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b); | |
} | |
getImageBase64(url, callback) { | |
const toDataURL = (url) => { | |
return fetch(url) | |
.then(response => response.blob()) | |
.then(blob => { | |
return new Promise((resolve, reject) => { | |
var reader = new FileReader(); | |
reader.onloadend = () => resolve(reader.result); | |
reader.onerror = reject; | |
reader.readAsDataURL(blob); | |
}) | |
}); | |
}; | |
toDataURL(url) | |
.then((res) => { | |
callback(null, res); | |
}) | |
.catch((err) => { | |
callback(err); | |
}); | |
} | |
getAverageRGB(image) { | |
let blockSize = 5, // only visit every 5 pixels | |
defaultRGB = {r:0,g:0,b:0}, // for non-supporting envs | |
canvas = document.createElement('canvas'), | |
context = canvas.getContext && canvas.getContext('2d'), | |
data, width, height, | |
i = -4, | |
length, | |
rgb = {r:0,g:0,b:0}, | |
count = 0; | |
if (!context) { | |
return defaultRGB; | |
} | |
height = canvas.height = image.naturalHeight || image.offsetHeight || image.height; | |
width = canvas.width = image.naturalWidth || image.offsetWidth || image.width; | |
context.drawImage(image, 0, 0); | |
try { | |
data = context.getImageData(0, 0, width, height); | |
} catch(e) { | |
/* security error, img on diff domain */alert('x'); | |
return defaultRGB; | |
} | |
length = data.data.length; | |
while ( (i += blockSize * 4) < length ) { | |
++count; | |
rgb.r += data.data[i]; | |
rgb.g += data.data[i+1]; | |
rgb.b += data.data[i+2]; | |
} | |
// ~~ used to floor values | |
rgb.r = ~~(rgb.r/count); | |
rgb.g = ~~(rgb.g/count); | |
rgb.b = ~~(rgb.b/count); | |
return rgb; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment