Solution 1 :

I’ll leave this here for you to have a play with. The last thing I do is in fact putImageData. I guess the problem lies in one of the bits I don’t recognize, as mentioned in the comments.

"use strict";
//window.addEventListener('load', onLoadedCreateB64url, false);
window.addEventListener('load', onLoadedUseEmbeddedImage, false);

// 33x33 pixel image of front wheel
var b64ImgSrc2 = 'data:image/png;base64,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';

function onLoadedUseEmbeddedImage(evt)
{
    let img = document.querySelector('img');
    img.addEventListener('load', imgLoaded, false);
    img.src = b64ImgSrc2;
}

function imgLoaded(evt)
{
    let img = this;
    let can = document.querySelector('canvas');
    let ctx = can.getContext('2d');
    can.width = img.naturalWidth;
    can.height = img.naturalHeight;
    ctx.drawImage(img, 0, 0);
    
    
    //141,127,143 - a few vertical pixels on right hand side of rim
    
   // color: #8d7f8f;

    recolourInPlace(can, 141,127,143, 255,0,0)
}


function onLoadedCreateB64url(evt)
{
    let img = document.querySelector('img');
    
    let can = document.querySelector('canvas');
    can.width = img.naturalWidth;
    can.height = img.naturalHeight;
    
    let ctx = can.getContext('2d');
    ctx.drawImage(img,0,0);
    
    let src = can.toDataURL();
    console.log(src);
}

function recolourInPlace(canvas, rin,bin,gin, rout,gout,bout)
{
    let ctx = canvas.getContext('2d');
    let imgData = ctx.getImageData(0,0, canvas.width, canvas.height);
    let width = canvas.width, height = canvas.height;
    let data = imgData.data;
    
    for (var y=0; y<height; y++)
    {
        for (var x=0; x<width; x++)
        {
            let index = ((y*width)+x) *4;
            if (data[index+0]==rin && data[index+1]==bin && data[index+2]==gin)
            {
                data[index+0] = rout;
                data[index+1] = gout;
                data[index+2] = bout;
            }
        }
    }
    ctx.putImageData(imgData, 0, 0);
}
    <img/>
    <canvas></canvas>

Problem :

Well I have been trying to make pixel manipulation work with image on canvas.enter image description here

Basically what I am trying to achieve is swapping/replacing of colors present in the image which already been uploaded on the canvas with other custom colors. As you can see in the attached image is my canvas designer with uploaded image and to the left bottom of designer there are colors with bullet points which comes from the image(colors with bullet points are present in the image) and above that is my custom color palette.

Here is the steps I follow for swapping/replacing the colors from the image after image has been uploaded on the canvas

  1. Upload the image to the canvas
  2. Click the check box for the color to swap which comes from an uploaded image on canvas(eg purple checked with checkbox shown in image)
  3. click on any color from custom color palette(eg yellow shown in image) to replace the color in the image(eg purple should get replaced with yellow in the image)

Here is what I have done so far for pixel manipulation.The below part gets triggered as soon as I click on my custom colors after checking box of colors from image

 jQuery('ul').on('click','li.licolors',function() {
                    console.log("licolors");
                    var activeObject = canvas.getActiveObject();
                    if (activeObject && (activeObject.type === 'path')) {
                        activeObject.set("stroke",jQuery(this).css('background-color'));
                        activeObject.dirty = true;
                        canvas.renderAll();
                        updateCanvasState();
                    }
                    else if(activeObject && (activeObject.type === "image")){
                        if($('.checkboxlicolorsfromimage').is(':checked')){
                            var colorfromimage = $('.checkboxlicolorsfromimage').val().split(",");//splitting color of checked checkbox purple rgb(83,70,128,255)
                            var Rcfi = colorfromimage[0];//Red from image
                            console.log(Rcfi);
                            var Gcfi = colorfromimage[1];//Green from image
                            console.log(Gcfi)
                            var Bcfi = colorfromimage[2];//Blue from image
                            console.log("bcfi"+Bcfi);
                            var Acfi = colorfromimage[3];//Alpha from image
                            var colortoimage = getRGB(jQuery(this).css('background-color'));//this variable holds rgbvalue (yellow color rgb(255, 205, 0)) which I have to apply to the image
                            var Rcti = colortoimage.red;//Red apply to image
                            console.log(Rcti);
                            var Gcti = colortoimage.green;//Green apply to image
                            console.log(Gcti);
                            var Bcti = colortoimage.blue;//Blue apply to image
                            console.log(Bcti);
                            var target = new Image();
                            target.src = canvas.toDataURL();
                            canvas.getContext('2d').drawImage(target,0,0);
                            const imageData = canvas.getContext('2d').getImageData(0, 0, target.width, target.height);
                            for (var i = 0; i < imageData.data.length; i += 4) {
                                if(parseInt(imageData.data[i]) == parseInt(Rcti)){console.log(imageData.data[i]);
                                    imageData.data[i] = Rcfi;//Red
                                    console.log(Rcfi);
                                }
                                if(parseInt(imageData.data[i + 1]) == parseInt(Gcti)){console.log(imageData.data[i + 1]);
                                    imageData.data[i + 1] = Gcfi;//Green
                                    console.log(Gcfi);
                                }
                                if(parseInt(imageData.data[i + 2]) == parseInt(Bcti)){console.log(imageData.data[i + 2]);
                                    imageData.data[i + 2] = Bcfi;//Blue
                                    console.log(Bcfi);
                                }
                            }
                            canvas.getContext('2d').putImageData(imageData, 0, 0);
                            activeObject.dirty = true;
                            canvas.renderAll();
                            updateCanvasState();
                        }
                    }
                });

I not getting any errors or warnings I can see in the console that I am able to run the above code but it is not swapping my colors in the already uploaded image on the canvas.

  1. Is it even possible to swap/replace colors in the image after it has been uploaded to the canvas? then swap/replace specific color channels with our own color
  2. Most of the references I found said to be on image .onload
    https://pictureelement.github.io/html5tech/canvas-pixel-manipulation-and-animations.html
    https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas
    https://www.tutorialspoint.com/Change-colour-of-an-image-drawn-on-an-HTML5-canvas-element

Comments

Comment posted by Thomas Sablik

Have you tried to debug the code with the debugger?

Comment posted by A Haworth

Are you wanting to do exact color matching – because it looks as though your image is quite complex color-wise.

Comment posted by J. Doe

Yes debugged it by putting breakpoints in my browser console and I can see my console.logs prints the pixels in console

Comment posted by enhzflep

My couple of bucks can’t help but eye-off the possibility that you’ve updated your canvas properly, but somehow nuked it again with the

Comment posted by J. Doe

Yes I believe it should be possible to replace the specific color pixels with my custom color pixels not sure if that only works on while image is

By