Open marcelpi opened 8 years ago
Another weird behavior. Check the dominant color.
Happens the same here:
@marcelpi I think the larger issue is how many tabs you have open! :astonished:
But in all seriousness, this is weird!
I got a lot of wrong dominant colors - using it for logos, to get main logo color. All time dominant colors are very different from that on image. Please review your alghoritm. I found that pngs are working better then jpgs. Look at this example with google logo:
Dominant color is not valid for both but 1st palette color for png is ok - shouldn't 1st pallete color be dominant one?
Link to original png: http://medienrauschen.de/wp-content/uploads/2015/09/google-new-logo.png
+1
I ended up with more reliable results by counting colors instead of using color-thief. Attaching code in case others want to experiment or build upon it.
_getPalette = (image) => {
const canvas = document.createElement('canvas');
const size = 16;
const maxPaletteSize = 10;
const context = canvas.getContext('2d');
const pixelArray = []; // Contains arrays of [red, green, blue, freqency]
const palette = []; // Contains arrays of [red, green, blue]
canvas.width = size;
canvas.height = size;
context.imageSmoothingEnabled = false;
context.drawImage(image, 0, 0, size, size);
// Format is [r,g,b,a,r,g,b,a,...]
const pixels = context.getImageData(0, 0, size, size).data;
for (let i = 0; i < pixels.length / 4; i++) {
const offset = i * 4;
const red = pixels[offset];
const green = pixels[offset + 1];
const blue = pixels[offset + 2];
const alpha = pixels[offset + 3];
let matchIndex = undefined;
// Skip this pixel if transparent or too close to white
if (alpha === 0 || (red > 240 && blue > 240 && green > 240)) {
continue;
}
// See if the color is already stored
for (let j = 0; j < pixelArray.length; j ++) {
if (red === pixelArray[j][0] &&
green === pixelArray[j][1] &&
blue === pixelArray[j][2]) {
matchIndex = j;
break;
}
}
// Add the color if it doesn't exist, otherwise increment frequency
if (matchIndex === undefined) {
pixelArray.push([red, green, blue, 1]);
} else {
pixelArray[matchIndex][3]++;
}
}
// Sort pixelArray by color frequency
pixelArray.sort(function(a, b) {
return b[3] - a[3];
});
// Fill array with [red, green, blue] values until maxPaletteSize or
// until there are no more colors, whichever happens first
for (let i = 0; i < Math.min(maxPaletteSize, pixelArray.length); i++) {
palette.push([pixelArray[i][0], pixelArray[i][1], pixelArray[i][2]]);
}
return palette;
};
I'm having probably a related issue. The dominant color shoud be white or a color in the "whites" range. I'm using Color Thief to determine whether to use black or white text on my image, using extracted dominant color as reference.
Clearly the magenta is the dominant color, but color-thief indicates blue. (url)