Отключить рисование на черных пикселях

#javascript #fabricjs

#javascript #fabricjs

Вопрос:

У меня есть fabric.js холст, содержащий объект изображения, подобный этому: введите описание изображения здесь

Я могу рисовать на этом изображении несколькими цветами / кистями, но я не хочу рисовать поверх черных линий / пикселей. Это потому, что оно описывает стены на моем изображении.

Итак, если я, например, нарисую немного красного на холсте, это должно выглядеть так:

введите описание изображения здесь

Как вы можете видеть, черные линии должны сохраняться. Но большой вопрос в том, как мне это сделать в fabric.js ?

Я могу придумать два решения:

  1. Найдите место в fabric.js код, в котором вы рисуете. Добавьте флажок, если(this_pixel_is_black){больше ничего не делать} {нарисовать пиксель .. }
  2. Создайте (PHP) скрипт, который просматривает каждый пиксель исходного изображения. Если это черный пиксель, он будет нарисован на новом прозрачном холсте. Сохраните это изображение и добавьте его поверх другого fabric.js изображение. Затем, когда пользователь рисует, он должен рисовать это ПОД прозрачным холстом сверху.

У вас есть идеи получше? И я не знаю, как реализовать два предложения, которые у меня были.

Комментарии:

1. просто общая идея — как насчет использования 3 слоев (canvas): фон с удаленным черным цветом, слой рисования и верхний слой с только черным цветом фона. Таким образом, нарисуйте все, что вы хотите, на втором слое, черный цвет всегда будет сверху.

2. @ViliusL это также было решением, которое я предложил как «решение 2». И в конечном итоге решение, которое я реализовал. Это отлично работает! Смотрите мой ответ ниже для получения дополнительной информации.

Ответ №1:

Я решил это сам, используя предложение 2 в OP.

Просмотрел fabric.js источник и заметил метод, _finalizeAndAddPath который запускается при наведении курсора мыши после рисования. Этот метод запускает событие path:created .

При создании fabric.js на холсте я сначала создаю «фоновое» изображение, затем (с помощью PHP-скрипта) создаю прозрачное изображение, заполненное только черными пикселями.

Когда вызывается path:created событие, я перемещаю нарисованный контур назад, поэтому прозрачный слой все еще находится сверху. На самом деле это работает действительно великолепно!

Вы можете увидеть работающий JSFiddle здесь:http://jsfiddle.net/2u4h4 /

Если кого-то интересует PHP-скрипт, который переводит изображение в прозрачный png только с черными пикселями, он здесь:

 $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