• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

ICON PALETTE

HTML

HTML:
<!DOCTYPE html>
<html>
<body style="background-color: black">

<img id="imgImage" src="/icon.png" alt="notdefined" >

<div>
<canvas id="myCanvas" style="border:2px solid #000000;width:300px;height:300px;"> </canvas></div>
<canvas id="colorCanvas" style="border:2px solid #000000;background-color:#000000;width:500px;height:100px;"> </canvas>
</body>
<script src="script.js"></script>
</html>


JS


v1.10 : Added color naming


JavaScript:
var image = document.getElementById("imgImage");
image.crossOrigin = "";
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

var colorCanvas = document.getElementById('colorCanvas');
var colorContext = colorCanvas.getContext('2d');

//Crops the border
var cropIconBorder = 4;

window.onload = function() {
    cropIconBorder = (image.width*6.25)/100;
    canvas.height = image.height;
    canvas.width = image.width;
  context.drawImage(image, cropIconBorder, cropIconBorder,
                          image.width-cropIconBorder*2,image.height-cropIconBorder*2,
                          0,0,
                          image.width,image.height);
  Palette();
}

//
var useLeastDeviation = false;

//Number of buckets/ number of colors that pallette will contain
var colorAmount = 4;
//Chosen color for splitting the buckets 0 Red 1 Green 2 Blue
var mainColor = 0;
//Maximum value of chosen main color
var mainMax = 0;
//Filters out pixels that are darker than the blackValue
var blackValue = 20;


//This helps the last bucket to have more pixels. 0.75-1.00 advised.
var mainMaxScale = 0.90;


//Average value of the color
var rAverage = 0;
var gAverage = 0;
var bAverage = 0;

//Max value of the color
var rMax = 0;
var gMax = 0;
var bMax = 0;


//Pixels
var rgbs = [];



function Palette(){
    for(var x = 0; x < canvas.width; x++ ){
        for(var y = 0; y < canvas.height; y++){

            var pixel = context.getImageData(x, y, 1, 1);
            var data = pixel.data;
            if(data[0]<blackValue && data[1]<blackValue && data[2] <blackValue) continue;

              rgbs.push(data);

            rAverage += data[0];
            gAverage += data[1];
            bAverage += data[2];

            if(rMax < data[0]) rMax = data[0];
            if(gMax < data[1]) gMax = data[1];
            if(bMax < data[2]) bMax = data[2];
        }
    }

    rAverage /= rgbs.length;
    gAverage /= rgbs.length;
    bAverage /= rgbs.length;

    GetMainColorWithStandartDeviation();

    var buckets = BucketSort(rgbs,colorAmount);

    //Sort by how much pixels each bucket contains higher to lower
    buckets = InsertSortLength(buckets);

    colorCanvas.width=buckets.length*150;



    for(let i = 0; i < buckets.length; i++){
        let averageR = 0;
        let averageG = 0;
        let averageB = 0;
        for(let j = 0; j <buckets[i].length; j++){
            averageR += buckets[i][j][0];
            averageG += buckets[i][j][1];
            averageB += buckets[i][j][2];
        }

        //Draw Colors
        averageR = Math.floor(averageR/buckets[i].length);
        averageG = Math.floor(averageG/buckets[i].length);
        averageB = Math.floor(averageB/buckets[i].length);
        console.log("Bucket " + i + " length " + buckets[i].length + " R " + averageR + " G " +averageG + " B " + averageB);
        colorContext.beginPath();
        colorContext.fillStyle ='rgb('+averageR+','+averageG+','+averageB+')';
        colorContext.fillRect(i*120, 20, 80, 100);
        colorContext.stroke();
        colorContext.fillStyle ='#FFFFFF';
        colorContext.font = "16px Arial";
        colorContext.fillText(GetColorName(averageR,averageG,averageB), i*120, 150);

    }
}


function GetColorName(r,g,b){
    var name = "";
    var approx = 512;
    for(let i = 0; i < colors.length; i++){
        let color = colors[i];
        var newApprox = Math.abs((color.r - r)) + Math.abs((color.g - g)) + Math.abs((color.b - b));
        if(newApprox < approx){
            approx = newApprox;
            name = color.name;
        }
    }


    return name;
}

class Color{
    constructor(r,g,b,name){
        this.r = r;
        this.g = g;
        this.b = b;
        this.name = name;
    }
}

var colors = [
new Color(    199, 21,133     ,"MediumVioletRed"),
new Color(    255, 20,147     ,"DeepPink"),
new Color(    219,112,147     ,"PaleVioletRed"),
new Color(    255,105,180     ,"HotPink"),
new Color(    255,182,193     ,"LightPink"),
new Color(    255,192,203     ,"Pink"),
new Color(    139,  0,  0     ,"DarkRed"),
new Color(    255,  0,  0     ,"Red"),
new Color(    178, 34, 34     ,"Firebrick"),
new Color(    220, 20, 60     ,"Crimson"),
new Color(    205, 92, 92     ,"IndianRed"),
new Color(    240,128,128     ,"LightCoral"),
new Color(    250,128,114     ,"Salmon"),
new Color(    233,150,122     ,"DarkSalmon"),
new Color(    255,160,122     ,"LightSalmon"),
new Color(    255, 69,  0     ,"OrangeRed"),
new Color(    255, 99, 71     ,"Tomato"),
new Color(    255,140,  0     ,"DarkOrange"),
new Color(    255,127, 80     ,"Coral"),
new Color(    255,165,  0     ,"Orange"),
new Color(    189,183,107     ,"DarkKhaki"),
new Color(    255,215,  0     ,"Gold"),
new Color(    240,230,140     ,"Khaki"),
new Color(    255,218,185     ,"PeachPuff"),
new Color(    255,255,  0     ,"Yellow"),
new Color(    238,232,170     ,"PaleGoldenrod"),
new Color(    255,228,181     ,"Moccasin"),
new Color(    255,239,213     ,"PapayaWhip"),
new Color(    250,250,210     ,"LightGoldenrodYellow"),
new Color(    255,250,205     ,"LemonChiffon"),
new Color(    255,255,224     ,"LightYellow"),
new Color(    128,  0,  0     ,"Maroon"),
new Color(    165, 42, 42     ,"Brown"),
new Color(    139, 69, 19     ,"SaddleBrown"),
new Color(    160, 82, 45     ,"Sienna"),
new Color(    210,105, 30     ,"Chocolate"),
new Color(    184,134, 11     ,"DarkGoldenrod"),
new Color(    205,133, 63     ,"Peru"),
new Color(    188,143,143     ,"RosyBrown"),
new Color(    218,165, 32     ,"Goldenrod"),
new Color(    244,164, 96     ,"SandyBrown"),
new Color(    210,180,140     ,"Tan"),
new Color(    222,184,135     ,"Burlywood"),
new Color(    245,222,179     ,"Wheat"),
new Color(    255,222,173     ,"NavajoWhite"),
new Color(    255,228,196     ,"Bisque"),
new Color(    255,235,205     ,"BlanchedAlmond"),
new Color(    255,248,220     ,"Cornsilk"),
new Color(       0,100,  0     ,"DarkGreen"),
new Color(       0,128,  0     ,"Green"),
new Color(      85,107, 47     ,"DarkOliveGreen"),
new Color(      34,139, 34     ,"ForestGreen"),
new Color(      46,139, 87     ,"SeaGreen"),
new Color(    128,128,  0     ,"Olive"),
new Color(    107,142, 35     ,"OliveDrab"),
new Color(      60,179,113     ,"MediumSeaGreen"),
new Color(      50,205, 50     ,"LimeGreen"),
new Color(       0,255,  0     ,"Lime"),
new Color(       0,255,127     ,"SpringGreen"),
new Color(       0,250,154     ,"MediumSpringGreen"),
new Color(    143,188,143     ,"DarkSeaGreen"),
new Color(    102,205,170     ,"MediumAquamarine"),
new Color(    154,205, 50     ,"YellowGreen"),
new Color(    124,252,  0     ,"LawnGreen"),
new Color(    127,255,  0     ,"Chartreuse"),
new Color(    144,238,144     ,"LightGreen"),
new Color(    173,255, 47     ,"GreenYellow"),
new Color(    152,251,152     ,"PaleGreen"),
new Color(       0,128,128     ,"Teal"),
new Color(       0,139,139     ,"DarkCyan"),
new Color(      32,178,170     ,"LightSeaGreen"),
new Color(      95,158,160     ,"CadetBlue"),
new Color(       0,206,209     ,"DarkTurquoise"),
new Color(      72,209,204     ,"MediumTurquoise"),
new Color(      64,224,208     ,"Turquoise"),
new Color(       0,255,255     ,"Aqua"),
new Color(       0,255,255     ,"Cyan"),
new Color(    127,255,212     ,"Aquamarine"),
new Color(    175,238,238     ,"PaleTurquoise"),
new Color(    224,255,255     ,"LightCyan"),
new Color(       0,  0,128     ,"Navy"),
new Color(       0,  0,139     ,"DarkBlue"),
new Color(       0,  0,205     ,"MediumBlue"),
new Color(       0,  0,255     ,"Blue"),
new Color(      25, 25,112     ,"MidnightBlue"),
new Color(      65,105,225     ,"RoyalBlue"),
new Color(      70,130,180     ,"SteelBlue"),
new Color(      30,144,255     ,"DodgerBlue"),
new Color(       0,191,255     ,"DeepSkyBlue"),
new Color(    100,149,237     ,"CornflowerBlue"),
new Color(    135,206,235     ,"SkyBlue"),
new Color(    135,206,250     ,"LightSkyBlue"),
new Color(    176,196,222     ,"LightSteelBlue"),
new Color(    173,216,230     ,"LightBlue"),
new Color(    176,224,230     ,"PowderBlue"),
new Color(      75,  0,130     ,"Indigo"),
new Color(    128,  0,128     ,"Purple"),
new Color(    139,  0,139     ,"DarkMagenta"),
new Color(    148,  0,211     ,"DarkViolet"),
new Color(      72, 61,139     ,"DarkSlateBlue"),
new Color(    138, 43,226     ,"BlueViolet"),
new Color(    153, 50,204     ,"DarkOrchid"),
new Color(    255,  0,255     ,"Fuchsia"),
new Color(    255,  0,255     ,"Magenta"),
new Color(    106, 90,205     ,"SlateBlue"),
new Color(    123,104,238     ,"MediumSlateBlue"),
new Color(    186, 85,211     ,"MediumOrchid"),
new Color(    147,112,219     ,"MediumPurple"),
new Color(    218,112,214     ,"Orchid"),
new Color(    238,130,238     ,"Violet"),
new Color(    221,160,221     ,"Plum"),
new Color(    216,191,216     ,"Thistle"),
new Color(    230,230,250     ,"Lavender"),
new Color(    255,228,225     ,"MistyRose"),
new Color(    250,235,215     ,"AntiqueWhite"),
new Color(    250,240,230     ,"Linen"),
new Color(    245,245,220     ,"Beige"),
new Color(    245,245,245     ,"WhiteSmoke"),
new Color(    255,240,245     ,"LavenderBlush"),
new Color(    253,245,230     ,"OldLace"),
new Color(    240,248,255     ,"AliceBlue"),
new Color(    255,245,238     ,"Seashell"),
new Color(    248,248,255     ,"GhostWhite"),
new Color(    240,255,240     ,"Honeydew"),
new Color(    255,250,240     ,"FloralWhite"),
new Color(    240,255,255     ,"Azure"),
new Color(    245,255,250     ,"MintCream"),
new Color(    255,250,250     ,"Snow"),
new Color(    255,255,240     ,"Ivory"),
new Color(    255,255,255     ,"White"),
new Color(       0,  0,  0     ,"Black"),
new Color(      47, 79, 79     ,"DarkSlateGray"),
new Color(    105,105,105     ,"DimGray"),
new Color(    112,128,144     ,"SlateGray"),
new Color(    128,128,128     ,"Gray"),
new Color(    119,136,153     ,"LightSlateGray"),
new Color(    169,169,169     ,"DarkGray"),
new Color(    192,192,192     ,"Silver"),
new Color(    211,211,211     ,"LightGray"),
new Color(    220,220,220     ,"Gainsboro"),
new Color(       0,0,63   ,"DimBlue"),
new Color(       63,0,0   ,"DimRed"),
new Color(       0,63,0   ,"DimGreen"),
new Color(       0,63,63  ,"DimCyan"),
new Color(       63,63,0   ,"DimYellow"),
new Color(       63,0,63   ,"DimMagenta")
];



//Uses Standart Deviation to determine the main color of the bucket sorting
function GetMainColorWithStandartDeviation(){
    let rVariance = 0;
    let gVariance = 0;
    let bVariance = 0;
    for(i = 0; i<rgbs.length; i++){
        rVariance += Math.pow(rgbs[i][0] - rAverage ,2);
        gVariance += Math.pow(rgbs[i][1] - gAverage ,2);
        bVariance += Math.pow(rgbs[i][2] - bAverage ,2);
    }

    rVariance /= rgbs.length;
    gVariance /= rgbs.length;
    bVariance /= rgbs.length;

    rDeviaton = Math.sqrt(rVariance);
    gDeviaton = Math.sqrt(gVariance);
    bDeviaton = Math.sqrt(bVariance);

    console.log(rDeviaton);
    console.log(gDeviaton);
    console.log(bDeviaton);


    maxDev= 0;
    if(rDeviaton > maxDev){
        maxDev = rDeviaton;
        mainMax = rMax;
        mainColor = 0;
    }

    if(gDeviaton > maxDev){
        maxDev = gDeviaton;
        mainMax = gMax;
        mainColor = 1;
    }

    if(bDeviaton > maxDev){
        maxDev = bDeviaton;
        mainMax = bMax;
        mainColor = 2;
    }

    if(useLeastDeviation){
        if(rDeviaton < maxDev){
        maxDev = rDeviaton;
        mainMax = rMax;
        mainColor = 0;
        }
        if(gDeviaton < maxDev){
            maxDev = gDeviaton;
            mainMax = gMax;
            mainColor = 1;
        }
        if(bDeviaton < maxDev){
            maxDev = bDeviaton;
            mainMax = bMax;
            mainColor = 2;
        }

    }



}


function BucketSort(array,k){
    var buckets =[];
    for(let i = 0; i < k; i++){
        buckets.push([]);
    }
    M = mainMax*mainMaxScale;

    for(let i = 0; i < array.length; i++){
        var position = Math.floor((k-1)*array[i][mainColor]/M);
        if(position > k-1) position = k-1;
        buckets[position].push(array[i]);
    }


    return buckets;
}



function InsertSortLength(buckets){
    let i = 1;
    while(i < buckets.length){
        let j = i;
        while(j>0 && buckets[j-1].length < buckets[j].length){
            let temp = buckets[j];
            buckets[j] = buckets[j-1];
            buckets[j-1] = temp;
            j--;
        }
        i++;
    }

    return buckets;
}
Last edited:
Top