0

I am using Color-Thief to extract a color palette from an image. And I've already extracted the colors using JavaScript.

<img src="my-image.jpg" id="uploadedImage" alt="Uplaoded Image>

<script type="text/javascript">
    var image = document.getElementById("uploadedImage");
                    var colorThief = new ColorThief();
                    var palette = colorThief.getPalette(image, 8);
                    for (color in palette) {
                        var firstColor = palette[0];
                        var secondColor = palette[1];
                        var thirdColor = palette[2];
                        var fourthColor = palette[3];
                        var fifthColor = palette[4];
                        var sixthColor = palette[5];
                        var seventhColor = palette[6];
                        var eighthColor = palette[7];
                    }

</script>

The colors extracted for example are:

(7) [Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3)]
0
:
(3) [55, 30, 41]
1
:
(3) [210, 111, 74]
2
:
(3) [121, 196, 212]
3
:
(3) [144, 62, 57]
4
:
(3) [101, 66, 100]
5
:
(3) [189, 174, 192]
6
:
(3) [164, 116, 133]

But my problem is that I cannot convert these Arrays into colors to display. Is there any way to do that?

I have read this question, but the answer doesn't help me figure out the way to solve my problem.

The answer to this question doesn't consider getting the colors dynamically from images neither displaying the colors. It's just converting from one space to another.

SIDE NOTE: If you want to try the Color-Thief, you have to have a server, because it calls AJAX.

Tes3awy
  • 2,166
  • 5
  • 29
  • 51

4 Answers4

3

If you have array of arrays, where each of the sub arrays has 3 items representing the R, B and G, you can convert them to hexadecimal notation using the link in your question:

ar = [
  [55, 30, 41],
  [210, 111, 74],
  [121, 196, 212],
  [144, 62, 57],
  [101, 66, 100],
  [189, 174, 192],
  [164, 116, 133]
]
res = ar.map(([r, g, b]) => ["#", r.toString(16), g.toString(16), b.toString(16)].join(""))
console.log(res);

document.getElementById("container").innerHTML = res.map((color) => `<div class='color-box' style='background: ${color};'></div>`).join("")
div.color-box {
  width: 50px;
  height: 50px;
  margin: 15px;
  float: left;
}
<div id="container"></div>
Dekel
  • 60,707
  • 10
  • 101
  • 129
  • Consider using array destructuring `ar.map(([r, g, b]) => ...` – Naftali Aug 16 '17 at 17:45
  • You'll also want to do zero padding for when values are less than 16. – vox Aug 16 '17 at 17:51
  • I want to display the colors either in the HEX or in the RGB Format. The color space doesn't matter my case. – Tes3awy Aug 16 '17 at 17:54
  • @OsamaAbbas so what is the problem with the above answer? – Dekel Aug 16 '17 at 17:55
  • @vox I'm not sure I understand the comment. Can you explain please? – Dekel Aug 16 '17 at 17:56
  • @Dekel Okay, let my clarify as much as my English can :D. Your answer converts the Array of 3 numbers [x,y,z] to RRGGBB. Your solution is much better than the other solutions from the questions I added. But What I want is to convert this Array (color) to something like a palette as in the Color-Thief site does when you press the `click button` – Tes3awy Aug 16 '17 at 17:59
  • Explain where/what exactly is the problem. Creating the HTML? extract the colors? Convert from rgb to hex? – Dekel Aug 16 '17 at 18:01
  • @Dekel Previewing the colors is the problem. – Tes3awy Aug 16 '17 at 18:04
  • @Dekel, after the many modifications the OP has asked for to my answer I think yours could be made to more succinctly handle all the additional requests. – Steve0 Aug 17 '17 at 16:21
1

This solution uses jQuery to set the background color of a bunch of div to the colors in the array.

var colorData = [
  [55, 30, 41],
  [210, 111, 74],
  [121, 196, 212],
  [144, 62, 57],
  [101, 66, 100],
  [189, 174, 192],
  [164, 116, 133]
];
$(function() {
  var $placeholder = $("#placeholder");
  var $tmp;
  $.each(colorData, function(idx, elem) {
    $tmp = $("<div class='colorize'></div>");
    $tmp.css("background-color", "rgb(" + this[0] + "," + this[1] + "," + this[2] + ")");
    //$tmp.append($("<span>").text($tmp.css('background-color')));
    $tmp.append($("<span>").text("#" +
      twoDigitHex(this[0]) +
      twoDigitHex(this[1]) +
      twoDigitHex(this[2])));
    $placeholder.append($tmp);
  });
});

function twoDigitHex(val) {
  return ("00" + val.toString(16)).substr(-2).toUpperCase();
}
div.colorize {
  display: inline-block;
  height: 75px;
  width: 75px;
  border: 1px solid black;
  margin: 3px;
}

div.colorize>span {
  position: relative;
  top: 75px;
  font-size: 8pt;
  white-space: nowrap;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='placeholder'></div>

Edit: adjusted snippet to put background color as text

Edit: variable font color (black | white)

Edit: change text to put it in a span, position that span under the div.

Edit: as requested combined a few different answers to this question to display the HEX color value instead of RGB.

Edit: Combined the other answers in to this question to hopefully create a more succinct and understandable variant below;

var colorData = [
  [55, 30, 41],
  [210, 111, 74],
  [121, 196, 212],
  [144, 62, 57],
  [101, 66, 100],
  [189, 174, 192],
  [164, 116, 133]
];
$(function() {
  colorData.map(([r, g, b]) => {
    displaySwatch(`#${twoDigitHex(r)}${twoDigitHex(g)}${twoDigitHex(b)}`);
  });
});

function displaySwatch(hex) {
  var $placeholder = $("#placeholder");
  var $tmp = $("<div class='colorize'></div>");
  $tmp.css("background-color", hex);
  $tmp.append($("<span>").text(hex));
  $placeholder.append($tmp);
}

function twoDigitHex(val) {
  return ("00" + val.toString(16)).substr(-2).toUpperCase();
}
div.colorize {
  display: inline-block;
  height: 50px;
  width: 50px;
  border: 1px solid black;
  margin: 3px;
}

div.colorize>span {
  position: relative;
  top: 50px;
  font-size: 8pt;
  white-space: nowrap;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='placeholder'></div>
Steve0
  • 2,233
  • 2
  • 13
  • 22
  • Thanks bro. Works like a charm (Y). You saved the day. – Tes3awy Aug 16 '17 at 18:06
  • Do you have any idea how to display the color code as well with the colored box? I mean beneath the colored box. – Tes3awy Aug 16 '17 at 18:18
  • I can't preview the color code in hex; the text inside or beneath the colored box. I get [object object] instead when I convert the color space to hex. Can you help me please ? – Tes3awy Aug 17 '17 at 09:37
  • 1
    combined parts of Dekel's answer and Yasser's to produce the hex value for display. – Steve0 Aug 17 '17 at 16:16
1

Dekel's answer should work fine in most cases. I have made only a minor addition to his answer. The numbers can be < 16, so they have to be padded with a "0" to be treated as color values.

ar = [
  [9, 8, 7],
  [55, 30, 41],
  [210, 111, 74],
  [121, 196, 212],
  [144, 62, 57],
  [101, 66, 100],
  [189, 174, 192],
  [164, 116, 133]
]

function toPaddedHexVal(val) {
  var hexVal = val.toString(16);
  return hexVal.length < 2 ? "0" + hexVal : hexVal;
}

res = ar.map(colorArray => "#" + colorArray.map(toPaddedHexVal).join(""))
console.log(res);
Yasser Hussain
  • 854
  • 7
  • 21
0

JavaScript colors may be specified by strings; for example, 'red' and '#123456'. Since you have the primary values, you could build a color specification string from, say, firstColor, as follows:

var colorSpecification = 'rgb(' + firstColor[0].toString() + ',' + firstColor[1].toString() + ',' + firstColor[2].toString() + ')';

For your example, that should produce a string value of 'rgb(55,30,41)'.

Be advised that JavaScript color specification is somewhat arcane. While specifications such as 'rgb(10,20,30)', '#123456', and '#12345678' are accepted, so are specifications such as 'red', 'yellow', and 'blue'. Even 'chucknorris' is reputed to be acceptable!

We B Martians
  • 367
  • 2
  • 12