3

So here is my problem: I have black and white images (img tags), and i want to change the color of it except for the black pixels. I used a code that allowed me to do this, but when coloring the image, some of the black pixels are colored too, not only the white as you can see in these images (some of the black lines are colored):

image to color Result i get

This is my code (to test it please change the image url to a local image so the color changing works)

let hex
var mug=document.getElementById("eyes");
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var originalPixels = null;
var currentPixels = null;
let currentcolor

function color(elem) {
  hex='rgb(0,0,0)'
  if (elem.classList[0].toString()=='color') {
    currentcolor=document.getElementById(elem.id).style.backgroundColor
    hex=currentcolor.toString()
  }
  
}

function color1(elem) {
document.getElementById(elem.id).style.fill=currentcolor
    getPixels(mug)
    hex=hex.substring(4, hex.length-1)
      .replace(/ /g, '')
      .split(',')
    changeColor(hex[0],hex[1],hex[2])
}


function getPixels(img)
{
    canvas.width = img.width;
    canvas.height = img.height;

    ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, img.width, img.height);
    originalPixels = ctx.getImageData(0, 0, img.width, img.height);
    currentPixels = ctx.getImageData(0, 0, img.width, img.height);

    img.onload = null;
}

function hexToRGB(hex)
{
  console.log(hex)
    var long = parseInt(hex.replace(/^#/, ""), 16);
    return {
        R: (long >>> 16) & 0xff,
        G: (long >>> 8) & 0xff,
        B: long & 0xff
    };
}

function changeColor(a,b,c)
{
    if(!originalPixels) return; // Check if image has loaded
    var newColor = {R: eval(a), G: eval(b), B: eval(c)};

    for(var I = 0, L = originalPixels.data.length; I < L; I += 4)
    {
        if(currentPixels.data[I + 3] > 0) // If it's not a transparent pixel
        {
          console.log(currentPixels.data[I + 3])
           if ((currentPixels.data[I]!=0 && currentPixels.data[I+1]!=0 && currentPixels.data[I+2]!=0)) {
            currentPixels.data[I] = newColor.R;
            currentPixels.data[I + 1] = newColor.G;
            currentPixels.data[I + 2] = newColor.B;
           }
        }
    }
    console.log(newColor)
    ctx.putImageData(currentPixels, 0, 0);
    mug.src = canvas.toDataURL("image/png");
}
#boite {
    width: 70%;
    height: 85%;
    border: 5px solid black;
    background-color: #e3e2d3;
    position: absolute;
    left: 0;
    right: 0;
    top: 5%;
    justify-content: center;
    display: flex;
    align-items: center;
    margin-left: 285px;
}
#corps{
    
    width: 300px;
}

#next2{
    position: absolute;
    width: 25%;
    height: 95%;
    text-align: center;
    justify-content: center;
    align-items: center;
    border-radius: 20px;
    border: 3px solid white;
    margin-left: 15px;
    margin-top: 15px;
    text-align: center;
    background-color: #B393DE;
}

#colours {
    
  color: #fff;
  justify-content: center;
  font: 100 24px/100px sans-serif;
  height: 150px;
  width: 100%;
  text-align: center;
  display: flex;
  flex-wrap: wrap;
}

#colours div {
    height: 50%;
    width: 30%;
    border: 2px solid rgb(255, 255, 255);
    border-radius: 50%;
    cursor:pointer;
  }
.color{

    background-color: #888888;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js" integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <title>Document</title>
</head>
<body>
    <div id="next2" >
  <div id="colours">
    <div id="red" class="color" style="background-color: #FE2712;" onclick="color(this)"></div>
  <div id="red-orange" class="color" style="background-color:#FD5206;" onclick="color(this)"></div>
  <div id="orange" class="color" style="background-color: #FB9902;" onclick="color(this)"></div>
  <div id="yellow-orange" class="color" style="background-color: #F9BC02;" onclick="color(this)"></div>
  <div id="yellow" class="color" style="background-color: #FFFE34;" onclick="color(this)"></div>
  <div id="yellow-green" class="color" style="background-color: #D1EA2C;" onclick="color(this)"></div>
  <div id="green" class="color" style="background-color: #66B033;" onclick="color(this)"></div>
  <div id="blue-green" class="color" style="background-color: #038FCB;" onclick="color(this)"></div>
  <div id="blue" class="color" style="background-color: #0247FE;" onclick="color(this)"></div>
  <div id="blue-violet" class="color" style="background-color: #3E01A4;" onclick="color(this)"></div>
  <div id="violet" class="color" style="background-color: #8601B0;" onclick="color(this)"></div>
  <div id="red-violet" class="color" style="background-color: #A9174B;" onclick="color(this)"></div>
  <div id="black" class="color" style="background-color: #000000;" onclick="color(this)"></div>
  <div id="white" class="color" style="background-color: #ffffff;" onclick="color(this)"></div>
  </div>
</div>
<div id="boite">

    <svg version="1.0" xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 1876.000000 2501.000000"
    preserveAspectRatio="xMidYMid meet" id="corps"  width="80%" height="80%">
   
   <g transform="translate(0.000000,2501.000000) scale(0.100000,-0.100000)"
   fill="white" stroke="none" id="issasvg" onclick="color1(this)" >
   <path d="M8615 24873 c-386 -22 -661 -48 -938 -88 -960 -140 -1780 -418 -2486
   -844 -317 -192 -473 -310 -721 -546 -164 -157 -264 -231 -362 -267 -44 -16
   -62 -28 -69 -46 -13 -34 6 -80 36 -88 12 -3 99 17 198 45 97 28 179 51 183 51
   5 0 -50 -39 -121 -86 -602 -401 -1138 -934 -1593 -1586 -602 -861 -1038 -1873
   -1357 -3148 -106 -420 -113 -462 -145 -834 -70 -801 -109 -1055 -242 -1591
   -139 -561 -163 -730 -163 -1145 0 -197 4 -325 13 -385 23 -153 62 -325 99
   -435 39 -119 144 -344 175 -377 22 -24 62 -30 88 -13 8 5 49 112 91 237 l76
   228 8 -50 c59 -407 298 -971 616 -1453 87 -132 132 -179 182 -193 95 -25 146
   38 175 217 9 57 20 104 24 104 4 0 8 -5 8 -10 0 -6 25 -67 56 -137 146 -331
   327 -595 579 -848 226 -227 390 -356 697 -547 l178 -110 -46 -57 c-935 -1156
   -1523 -2549 -1683 -3986 -37 -329 -45 -485 -45 -865 0 -388 13 -603 55 -945
   106 -867 372 -1742 769 -2534 67 -134 80 -151 119 -151 53 0 61 23 61 166 0
   71 3 152 6 181 l7 52 76 -112 c339 -495 585 -798 841 -1035 538 -498 1161
   -855 1925 -1105 779 -254 1708 -374 2624 -338 331 13 498 26 896 71 149 16
   275 30 280 30 16 -1 -64 -41 -140 -71 -81 -31 -104 -59 -83 -103 6 -15 23 -30
   37 -34 42 -12 555 -7 696 7 575 55 1056 184 1816 487 773 307 1301 585 1764
   929 441 326 806 720 1058 1139 60 100 77 122 82 106 3 -11 8 -105 9 -208 2
   -104 6 -195 11 -201 12 -20 53 -31 79 -21 41 15 261 480 408 865 693 1807 684
   3785 -27 5580 -301 759 -688 1413 -1243 2096 l-23 28 101 76 c213 161 427 344
   750 641 369 338 548 553 690 825 l57 111 17 -109 c9 -59 22 -125 28 -145 25
   -85 119 -123 188 -76 95 64 374 521 518 848 116 261 219 591 238 761 4 33 10
   57 14 52 4 -4 40 -106 80 -226 61 -186 76 -220 96 -229 53 -25 73 -5 155 157
   316 626 333 1410 49 2340 -29 94 -70 229 -92 300 -37 122 -514 1993 -592 2320
   -57 240 -100 447 -170 813 -108 559 -164 803 -256 1107 -223 739 -541 1319
   -968 1766 -59 62 -102 110 -97 107 20 -11 461 -148 478 -148 25 0 57 36 57 66
   0 15 -12 37 -32 56 -53 49 -204 159 -328 238 -150 95 -268 183 -465 344 -631
   517 -1140 856 -1725 1150 -1004 506 -2012 758 -3295 826 -167 9 -976 11 -1110
   3z"/>
   </g>
   </svg> 
<img id="eyes" width="80px" height="40px" src="https://png.pngitem.com/pimgs/s/35-355887_eyes-eye-black-and-white-clip-art-cartoon.png" id="eye1-boite0" class="eye1-boite0 remove" style="position: absolute; width:150px; height:auto" onclick="color1(this)">
</div>
</body>
</html>

Thanks for your help!

Nour Hariz
  • 75
  • 5
  • (offtopic) No need to import jQuery if you don't use it. – Roko C. Buljan Jan 02 '23 at 23:49
  • Isn't the issue that you test for complete blackness `#000000`, whereas a black looking value like `#010003` is assigned another color? You can test for a luminosity threshold using a simplified `if (currentPixels.data[I] + currentPixels.data[I+1] + currentPixels.data[I+2] > 10)` – Peter Thoeny Jan 03 '23 at 03:03
  • Also, your first image shows strong anti-aliasing for the lines, which reduces/removes the blackness, hence the need to use a luminosity threshold – Peter Thoeny Jan 03 '23 at 03:08
  • @PeterThoeny i tried your solution but the result didn't change :( what do you mean by strong anti-aliasing please? – Nour Hariz Jan 07 '23 at 21:52
  • https://en.wikipedia.org/wiki/Spatial_anti-aliasing – Peter Thoeny Jan 08 '23 at 03:48

0 Answers0