25

First of all I am sorry for the stupid question I am going to ask. I have an image of a mug. When any user picks a color code from color picker I want to turn the color of the mug to that color.

Would you please kindly give me a hint on how to do this using jquery? I am planning to achieve this using PHP and Jquery.

Thanks in Advance :)

P.S It just occurred to me that its not possible to change the color of an object using a color picker if it is in an image format but still there got to be a way to achieve this. Would you please kindly suggest me something?

black_belt
  • 6,601
  • 36
  • 121
  • 185
  • 2
    Could you show us the image file? Depending on it's complexity it may be possible to achieve good results using canvas. – Delta Feb 16 '12 at 00:26
  • @Delta thanks for you reply. I tried to upload the image but stackoverflow.com didn't let me to... said that I need more than 10 reputation. However I have uploaded the image to tinypic. Here is the link http://i42.tinypic.com/20zz140.jpg :) thanks again – black_belt Feb 16 '12 at 00:34
  • @Delta. I have given you think link to my image. Do you think using "Canvas" will do the trick for me. Because as you will see the color of my mug is white.. if any user uses a color picker and picks the red color and then changing mind immediately picks yellow.. the color of mug will turn to yellow+red. It will not replace the red with yellow. Please correct me if I am wrong. thanks :) – black_belt Feb 16 '12 at 01:12
  • 1
    Oh yes, it will do the trick, I was a little busy, I am working on my answer right now. Do you want it to be red+yellow or just yellow in that case? It can be done anyway you want. – Delta Feb 16 '12 at 01:30
  • I just want it to be yellow and you already have done that for me. :) Thanks man for your time. :) – black_belt Feb 16 '12 at 04:43

4 Answers4

72

Ok, first step, instead of using jpeg format, you're going to use the PNG so you can have transparent areas on the image.

Open it on an image editor and cut out all the blank areas on the image, leaving the mug with a transparent contour. Like this:

enter image description here

We are not going to use jQuery here because honestly I know nothing about it so I can't help you with that, instead we're going to use directly the canvas API from HTML 5 (this means your app will not work on older browsers)

Here we will perform a per-pixel color multiplication, since your mug is in gray scale that will do it for us.

Let's pick an array containing all of the pixels color information.

  1. Add the image to the DOM
  2. Create an offscreen canvas element
  3. Wait for the image to load
  4. Draw the image on the canvas
  5. Get the pixels data using the getImagedata method, inside the onload event of the image

    <*img src="mug.png" id="mug" width="25%" height="25%" onload="getPixels(this)" />

    var mug = document.getElementById("mug");
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");
    var originalPixels = null;
    var currentPixels = null;
    
    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;
    }
    

We need the color from the color picker to be in the RGB format, not hex, so use this function in case your picker returns a hexadecimal value to convert it:

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

Now here is the magic part, let's loop through the pixel data and multiply it to the color from the color picker.

on my script there is no color picker, I have just created a simple text input to type in the hexadecimal color, this function below is the onclick event of an input button

    function changeColor()
    {
        if(!originalPixels) return; // Check if image has loaded
        var newColor = hexToRGB(document.getElementById("color").value);

        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
            {
                currentPixels.data[I] = originalPixels.data[I] / 255 * newColor.R;
                currentPixels.data[I + 1] = originalPixels.data[I + 1] / 255 * newColor.G;
                currentPixels.data[I + 2] = originalPixels.data[I + 2] / 255 * newColor.B;
            }
        }

        ctx.putImageData(currentPixels, 0, 0);
        mug.src = canvas.toDataURL("image/png");
    }

See, the trick is:

  • Get the original pixel color
  • Convert it from range 0-255 to 0-1
  • Multiply it to the new color you want it to be.

You can see it working here: http://users7.jabry.com/overlord/mug.html

  • I am sure it works at least on firefox and chrome.

  • The mug contour doesn't look good, that's because I just did a quick "magic wand" on photoshop, you can do something better later.

Delta
  • 4,308
  • 2
  • 29
  • 37
  • Keep in mind, this method doesn't support 3digit hex codes, 6 digit only – SpYk3HH Feb 16 '12 at 03:55
  • 3
    @Delta I cannot thank you enough. man... You just made it ready :) It works just perfectly.. amazing. :) – black_belt Feb 16 '12 at 04:48
  • 9
    The demo link is dead –  Jun 17 '13 at 10:16
  • Works like magic, you helped me alot – yossico Nov 21 '13 at 09:26
  • @Delta i know this is an old link but, is it possible to do this with a background PNG image? – DJ22T Dec 12 '13 at 16:01
  • @DannyG I'm not sure if I understand what you mean. Clarify it a little bit – Delta Dec 12 '13 at 21:33
  • @Delta suppose that i have a `
    ` and in the css i have `.mug{background-image:url(mug.png); }` is it possible to change the background image color using a similar method? or this one tbp?
    – DJ22T Dec 12 '13 at 21:56
  • Well, yes. You can use the edited image anywhere as you would normaly. Maybe this would do: `document.querySelector("#mug").style.backgroundImage = "url(" + canvas.toDataURL("image/png") + ")";` – Delta Dec 13 '13 at 00:34
  • Do you think you could help me adapt this to change multiple images on one page? For example, I enter one color and press "change color" and then enter another color and press a SECOND change color button and both colors are shown at the same time. Having two images and two canvases. – aboutros Jan 15 '15 at 07:15
  • I have made a library from this answer, you can find it here https://github.com/juangirini/imgColorChanger.js – Juan Girini Mar 09 '19 at 11:35
  • The link _http://users7.jabry.com/overlord/mug.html_ isn't working anymore. Maybe you can update it. – MrMaavin Mar 26 '19 at 08:35
18

You could use a knock-out picture of a mug with transparent areas, give it a background and change the color of the background as required. cssTricks

Here's a basic example, jsFiddle, using Farbtastic Color Picker.

$('#colorpicker').farbtastic(function(color){
    $('img').css("background-color",color);
});​
Sinetheta
  • 9,189
  • 5
  • 31
  • 52
14

You should use "Product Colorizer" by Nik Korablin. It supports one or two colors, and is simple to set up.

MrMaavin
  • 1,611
  • 2
  • 19
  • 30
adamdehaven
  • 5,890
  • 10
  • 61
  • 84
2

You could overlay an absolutely positioned .png with a z-index greater than the base image of the mug. The overlay would be the colored mug and could have the background knoced out if needed. Swap the overlay as needed via an event handler- maybe add/remove a class?

shaunsantacruz
  • 8,903
  • 3
  • 19
  • 19