简体   繁体   中英

Disable drawing on black pixels

I have a fabric.js canvas that contains an image object like this: 在此处输入图片说明

I can draw on that image with several colors/brushes, but I don't want to draw over the black lines/pixels. This is because it describes the walls on my image.

So if I eg draw some red on the canvas, it should look like this:

在此处输入图片说明

As you can see, the black lines should persist. But the big question is: How do I do that in fabric.js?

I can think of two solutions:

  1. Find the place in fabric.js code where you draw. Add a check if(this_pixel_is_black){ don't do anything }else{ draw the pixel.. }
  2. Make a (PHP) script that goes through every pixel of the source image. If it's a black pixel, it will be drawn on a new transparent canvas. Save that image, and add it on top of the other fabric.js image. Then, when the user draws, it should draw it BELOW the transparent canvas on top.

Do you have any better ideas? And I don't know how to implement the two suggestions I had.

I solved it myself using suggestion 2 in the OP.

Looked through the fabric.js source and noticed the method _finalizeAndAddPath that fires on mouseUp after having drawn. That method fires an event path:created .

When making a fabric.js canvas, I first create the "background" image, then I (via a PHP script) create a transparent image with only the black pixels filled.

When the path:created event is thrown, I move the drawn path backwards, so the transparent layer is still on top. It actually works really really great!

You can see a working JSFiddle here: http://jsfiddle.net/2u4h4/

If anyone is interested in the PHP script that translates the image to a transparent png with only the black pixels, it's here:

$img = imagecreatefrompng('source.png');
$width = imagesx($img);
$height = imagesy($img);

//Placeholder to transparent image
$img_transp = imagecreatetruecolor($width, $height);

//Make image transparent (on white)
$index = imagecolorexact($img_transp, 255, 255, 255); 
imagecolortransparent($img_transp, $index); 
imagefill($img_transp, 0, 0, $index);

$black = imagecolorallocate($img_transp, 0, 0, 0);

//Loop every pixel
for($x = 0;$x < $width;$x++){
    for($y = 0;$y < $height;$y++){
        if(imagecolorat($img, $x, $y) == 0){ //Is the pixel black?
            imagesetpixel($img_transp, $x, $y, $black); //Draw the black pixel
        }
    }
}

header('Content-Type: image/png');
imagepng($img_transp); //Show the image to the user

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM