Search code examples
phpjavascriptimagemagicktransparencyfabricjs

fabric js or imagick remove white from image


I got this situation which is hard for me to search on Google and explain.

Our company prints photos on aluminium and we give our customers two choices.

  1. The first choice is to print their pictures on aluminium just like they gave the picture to us, so if the picture has a white background the picture gets printed with a white background. Easy like that.

  2. The second option is that we can print their picture without using white. instead of all the "white values" (<- the best I can come up with to explain) being printed we leave it transparent.

I know there is this removeWhite filter in fabric JS which can replace white areas with transparent ones. But this is not what I need. I need a Fabric JS filter, ImageMagick thing or any other PHP or JS solution that can turn the "white value" of a pixel transparent. I know this stuff may sounds very vague to you guys, but let me try to explain this way:

  • If I come across a white pixel I need to make it transparent.

  • If I come across a grey pixel, I need to turn it from a combination of white and black into a combination of transparent and black.

  • If I come a cross a coloured pixel, I also need to turn the "white value" which makes it light turn to transparent.

Here is an before and after example of the filter/effect I try to accomplish:

Before:

After:

Please don't hesitate to ask me anything if you don't understand what I'm asking for.


Solution

  • I got it to work. By using factors from the YUV color space, I could create a Fabric JS image filter.

    It was a lot of Trial-and-error to get the result I was looking for. Therefore I don't have a (detailed) description of how this works. For all I know is that I have used the YUV factors to get the brightness of the (RGB) colours.

    for (i = 0; i < iLen; i++) {
        for (j = 0; j < jLen; j++) {
          index = (i * 4) * jLen + (j * 4);
          var yuv = {};
          yuv.r = data[index] / 255 * 1 * 0.299;     
          yuv.g = data[index + 1] / 255 * 1 * 0.587; //we use the yuv formula constants
          yuv.b = data[index + 2] / 255 * 1 * 0.114; //to try to catch the Y (brightness)
          yuv.y = yuv.r + yuv.g + yuv.b;             //you can tweak this
          data[index + 3] = 350 - (yuv.y / 1 * 255); //by changing the first number after the "=" on this line!
        }
    }
    

    Somehow by messing with the 350 on the last line you can alter the transparency factor.

    Sorry for not being able to explain more about how this Fabric filter works.