Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 画布泛光填充笔划颜色_Javascript_Canvas - Fatal编程技术网

Javascript 画布泛光填充笔划颜色

Javascript 画布泛光填充笔划颜色,javascript,canvas,Javascript,Canvas,我正在使用canvas构建一个小应用程序。我的应用程序将有一个选项来填充黑白图像 我下载了一个代码,工作正常,但它只在图像笔划为黑色时工作。我将要使用的所有图像都是灰色笔划 所以,我想知道我需要做什么改变,才能使代码使用灰色笔划,而不是黑色笔划 代码如下: HTML: JavaScript var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); var $canvas =

我正在使用canvas构建一个小应用程序。我的应用程序将有一个选项来填充黑白图像

我下载了一个代码,工作正常,但它只在图像笔划为黑色时工作。我将要使用的所有图像都是灰色笔划

所以,我想知道我需要做什么改变,才能使代码使用灰色笔划,而不是黑色笔划

代码如下:

HTML:


JavaScript

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var strokeColor = {
    r: 152,
    g: 152,
    b: 152
};
var fillColor = {
    r: 101,
    g: 155,
    b: 65
};
var fillData;
var strokeData;


// load image
var img = new Image();
img.onload = function () {
    start();
}
img.crossOrigin = "anonymous";
img.src = "http://i.imgur.com/kjY1kiE.png";


function matchstrokeColor(r, g, b, a) {
    // never recolor the initial black divider strokes
    // must check for near black because of anti-aliasing
    return (r + g + b < 100 && a === 155);
}

function matchStartColor(pixelPos, startR, startG, startB) {

    // get the color to be matched
    var r = strokeData.data[pixelPos],
        g = strokeData.data[pixelPos + 1],
        b = strokeData.data[pixelPos + 2],
        a = strokeData.data[pixelPos + 3];

    // If current pixel of the outline image is black-ish
    if (matchstrokeColor(r, g, b, a)) {
        return false;
    }

    // get the potential replacement color
    r = fillData.data[pixelPos];
    g = fillData.data[pixelPos + 1];
    b = fillData.data[pixelPos + 2];

    // If the current pixel matches the clicked color
    if (r === startR && g === startG && b === startB) {
        return true;
    }

    // If current pixel matches the new color
    if (r === fillColor.r && g === fillColor.g && b === fillColor.b) {
        return false;
    }

    return true;
}

// Thank you William Malone!
function floodFill(startX, startY, startR, startG, startB) {
    var newPos;
    var x;
    var y;
    var pixelPos;
    var neighborLeft;
    var neighborRight;
    var pixelStack = [
        [startX, startY]
    ];

    while (pixelStack.length) {

        newPos = pixelStack.pop();
        x = newPos[0];
        y = newPos[1];

        // Get current pixel position
        pixelPos = (y * canvasWidth + x) * 4;

        // Go up as long as the color matches and are inside the canvas
        while (y >= 0 && matchStartColor(pixelPos, startR, startG, startB)) {
            y -= 1;
            pixelPos -= canvasWidth * 4;
        }

        pixelPos += canvasWidth * 4;
        y += 1;
        neighborLeft = false;
        neighborRight = false;

        // Go down as long as the color matches and in inside the canvas
        while (y <= (canvasHeight - 1) && matchStartColor(pixelPos, startR, startG, startB)) {
            y += 1;

            fillData.data[pixelPos] = fillColor.r;
            fillData.data[pixelPos + 1] = fillColor.g;
            fillData.data[pixelPos + 2] = fillColor.b;
            fillData.data[pixelPos + 3] = 255;


            if (x > 0) {
                if (matchStartColor(pixelPos - 4, startR, startG, startB)) {
                    if (!neighborLeft) {
                        // Add pixel to stack
                        pixelStack.push([x - 1, y]);
                        neighborLeft = true;
                    }
                } else if (neighborLeft) {
                    neighborLeft = false;
                }
            }

            if (x < (canvasWidth - 1)) {
                if (matchStartColor(pixelPos + 4, startR, startG, startB)) {
                    if (!neighborRight) {
                        // Add pixel to stack
                        pixelStack.push([x + 1, y]);
                        neighborRight = true;
                    }
                } else if (neighborRight) {
                    neighborRight = false;
                }
            }

            pixelPos += canvasWidth * 4;
        }
    }
}

// Start a floodfill
// 1. Get the color under the mouseclick
// 2. Replace all of that color with the new color
// 3. But respect bounding areas! Replace only contiguous color.
function paintAt(startX, startY) {

    // get the clicked pixel's [r,g,b,a] color data
    var pixelPos = (startY * canvasWidth + startX) * 4,
        r = fillData.data[pixelPos],
        g = fillData.data[pixelPos + 1],
        b = fillData.data[pixelPos + 2],
        a = fillData.data[pixelPos + 3];

    // this pixel's already filled
    if (r === fillColor.r && g === fillColor.g && b === fillColor.b) {
        return;
    }

    // this pixel is part of the original black image--don't fill
    if (matchstrokeColor(r, g, b, a)) {
        return;
    }

    // execute the floodfill
    floodFill(startX, startY, r, g, b);

    // put the colorized data back on the canvas
    context.clearRect(0, 0, canvasWidth, canvasHeight);
    context.putImageData(fillData, 0, 0);
    context.drawImage(img, 0, 0);
}

// create a random color object {red,green,blue}
function randomColorRGB() {
    var hex = Math.floor(Math.random() * 16777215).toString(16);
    //var r = parseInt(hex.substring(0, 2), 16);

    var r = 155;
    var g = 155;
    var b = 255;

    //var g = parseInt(hex.substring(2, 4), 16);
    //var b = parseInt(hex.substring(4, 6), 16);
    return ({
        r: r,
        g: g,
        b: b
    });
}

// draw the image to the canvas and get its pixel array
// listen for mouse clicks and do floodfill when clicked
function start() {

    context.drawImage(img, 0, 0);
    strokeData = context.getImageData(0, 0, canvasWidth, canvasHeight);
    context.clearRect(0, 0, context.canvas.width, context.canvas.height);
    fillData = context.getImageData(0, 0, canvasWidth, canvasHeight);
    context.drawImage(img, 0, 0);

    $('#canvas').mousedown(function (e) {
        // Mouse down location
        var mouseX = parseInt(e.clientX - offsetX);
        var mouseY = parseInt(e.clientY - offsetY);
        // set a new random fillColor
        fillColor = randomColorRGB();
        // floodfill
        paintAt(mouseX, mouseY);
    });
var canvas=document.getElementById(“canvas”);
var context=canvas.getContext(“2d”);
var$canvas=$(“#canvas”);
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var canvasWidth=canvas.width;
var canvasHeight=canvas.height;
var strokeColor={
r:152,
g:152,
b:152
};
var fillColor={
r:101,
g:155,
b:65
};
var数据;
var-strokeData;
//加载图像
var img=新图像();
img.onload=函数(){
start();
}
img.crossOrigin=“匿名”;
img.src=”http://i.imgur.com/kjY1kiE.png";
函数匹配StrokeColor(r、g、b、a){
//切勿回忆最初的黑色分隔符笔划
//由于抗锯齿,必须检查是否接近黑色
回报率(r+g+b<100&&a==155);
}
功能匹配StartColor(像素位置、startR、startG、startB){
//获取要匹配的颜色
var r=strokeData.data[pixelPos],
g=strokeData.data[pixelPos+1],
b=strokeData.data[pixelPos+2],
a=strokeData.data[pixelPos+3];
//如果轮廓图像的当前像素为黑色
if(匹配strokeColor(r、g、b、a)){
返回false;
}
//获得潜在的替换颜色
r=fillData.data[pixelPos];
g=填充数据。数据[pixelPos+1];
b=fillData.data[pixelPos+2];
//如果当前像素与单击的颜色匹配
如果(r==startR&&g==startG&&b==startB){
返回true;
}
//如果当前像素与新颜色匹配
如果(r==fillColor.r&&g==fillColor.g&&b==fillColor.b){
返回false;
}
返回true;
}
//谢谢威廉·马龙!
功能注水(startX、startY、startR、startG、startB){
var newPos;
var x;
变量y;
var-pixelPos;
var neighborLeft;
邻里关系;
var pixelStack=[
[startX,startY]
];
while(pixelStack.length){
newPos=pixelStack.pop();
x=newPos[0];
y=新位置[1];
//获取当前像素位置
pixelPos=(y*画布宽度+x)*4;
//只要颜色匹配并且在画布内,就可以向上移动
而(y>=0&&matchStartColor(像素点、startR、startG、startB)){
y-=1;
pixelPos-=画布宽度*4;
}
pixelPos+=画布宽度*4;
y+=1;
邻里关系=假;
邻里关系=错误;
//只要颜色匹配,就在画布内向下移动
while(y0){
if(匹配StartColor(像素位置-4、startR、startG、startB)){
如果(!Neightarleft){
//将像素添加到堆栈
pixelStack.push([x-1,y]);
邻里关系=正确;
}
}else if(邻里金融){
邻里关系=假;
}
}
如果(x<(画布宽度-1)){
if(匹配StartColor(像素位置+4、startR、startG、startB)){
如果(!邻居){
//将像素添加到堆栈
pixelStack.push([x+1,y]);
邻里关系=正确;
}
}else if(邻里关系){
邻里关系=错误;
}
}
pixelPos+=画布宽度*4;
}
}
}
//开始注水
// 1. 在鼠标单击下获取颜色
// 2. 用新颜色替换所有该颜色
// 3. 但要尊重边界地区!仅替换连续颜色。
功能油漆(startX、startY){
//获取点击像素的[r,g,b,a]颜色数据
变量pixelPos=(星形*画布宽度+星形)*4,
r=fillData.data[pixelPos],
g=fillData.data[pixelPos+1],
b=填充数据。数据[pixelPos+2],
a=fillData.data[pixelPos+3];
//这个像素已经满了
如果(r==fillColor.r&&g==fillColor.g&&b==fillColor.b){
返回;
}
//此像素是原始黑色图像的一部分--不要填充
if(匹配strokeColor(r、g、b、a)){
返回;
}
//执行洪水填充
漫灌(startX、startY、r、g、b);
//将彩色数据放回画布上
clearRect(0,0,画布宽度,画布高度);
putImageData(fillData,0,0);
drawImage(img,0,0);
}
//创建一个随机颜色对象{红、绿、蓝}
函数randomColorRGB(){
var hex=Math.floor(Math.random()*16777215).toString(16);
//var r=parseInt(十六进制子串(0,2,16);
var r=155;
var g=155;
变量b=255;
//var g=parseInt(十六进制子串(2,4,16);
//var b=parseInt(十六进制子串(4,6,16);
返回({
r:r,
g:g,
b:b
});
}
//将图像绘制到画布并获取其像素阵列
//聆听鼠标点击,点击时进行泛光填充
函数start(){
drawImage(img,0,0);
strokeData=context.getImageData(0,0,画布宽度,画布高度);
clearRect(0,0,context.canvas.width,context.canvas.height);
fillData=context.getImageData(0,0,画布宽度,画布高度);
drawImage(img,0,0);
$(“#画布”).mousedown(函数(e){
//鼠标下键位置
var mouseX=parseInt(e.clientX-offsetX);
var mouseY=parseInt(e.clientY-offsetY);
//设置新的随机填充颜色
fillColor=randomColorRGB();
//填海
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var strokeColor = {
    r: 152,
    g: 152,
    b: 152
};
var fillColor = {
    r: 101,
    g: 155,
    b: 65
};
var fillData;
var strokeData;


// load image
var img = new Image();
img.onload = function () {
    start();
}
img.crossOrigin = "anonymous";
img.src = "http://i.imgur.com/kjY1kiE.png";


function matchstrokeColor(r, g, b, a) {
    // never recolor the initial black divider strokes
    // must check for near black because of anti-aliasing
    return (r + g + b < 100 && a === 155);
}

function matchStartColor(pixelPos, startR, startG, startB) {

    // get the color to be matched
    var r = strokeData.data[pixelPos],
        g = strokeData.data[pixelPos + 1],
        b = strokeData.data[pixelPos + 2],
        a = strokeData.data[pixelPos + 3];

    // If current pixel of the outline image is black-ish
    if (matchstrokeColor(r, g, b, a)) {
        return false;
    }

    // get the potential replacement color
    r = fillData.data[pixelPos];
    g = fillData.data[pixelPos + 1];
    b = fillData.data[pixelPos + 2];

    // If the current pixel matches the clicked color
    if (r === startR && g === startG && b === startB) {
        return true;
    }

    // If current pixel matches the new color
    if (r === fillColor.r && g === fillColor.g && b === fillColor.b) {
        return false;
    }

    return true;
}

// Thank you William Malone!
function floodFill(startX, startY, startR, startG, startB) {
    var newPos;
    var x;
    var y;
    var pixelPos;
    var neighborLeft;
    var neighborRight;
    var pixelStack = [
        [startX, startY]
    ];

    while (pixelStack.length) {

        newPos = pixelStack.pop();
        x = newPos[0];
        y = newPos[1];

        // Get current pixel position
        pixelPos = (y * canvasWidth + x) * 4;

        // Go up as long as the color matches and are inside the canvas
        while (y >= 0 && matchStartColor(pixelPos, startR, startG, startB)) {
            y -= 1;
            pixelPos -= canvasWidth * 4;
        }

        pixelPos += canvasWidth * 4;
        y += 1;
        neighborLeft = false;
        neighborRight = false;

        // Go down as long as the color matches and in inside the canvas
        while (y <= (canvasHeight - 1) && matchStartColor(pixelPos, startR, startG, startB)) {
            y += 1;

            fillData.data[pixelPos] = fillColor.r;
            fillData.data[pixelPos + 1] = fillColor.g;
            fillData.data[pixelPos + 2] = fillColor.b;
            fillData.data[pixelPos + 3] = 255;


            if (x > 0) {
                if (matchStartColor(pixelPos - 4, startR, startG, startB)) {
                    if (!neighborLeft) {
                        // Add pixel to stack
                        pixelStack.push([x - 1, y]);
                        neighborLeft = true;
                    }
                } else if (neighborLeft) {
                    neighborLeft = false;
                }
            }

            if (x < (canvasWidth - 1)) {
                if (matchStartColor(pixelPos + 4, startR, startG, startB)) {
                    if (!neighborRight) {
                        // Add pixel to stack
                        pixelStack.push([x + 1, y]);
                        neighborRight = true;
                    }
                } else if (neighborRight) {
                    neighborRight = false;
                }
            }

            pixelPos += canvasWidth * 4;
        }
    }
}

// Start a floodfill
// 1. Get the color under the mouseclick
// 2. Replace all of that color with the new color
// 3. But respect bounding areas! Replace only contiguous color.
function paintAt(startX, startY) {

    // get the clicked pixel's [r,g,b,a] color data
    var pixelPos = (startY * canvasWidth + startX) * 4,
        r = fillData.data[pixelPos],
        g = fillData.data[pixelPos + 1],
        b = fillData.data[pixelPos + 2],
        a = fillData.data[pixelPos + 3];

    // this pixel's already filled
    if (r === fillColor.r && g === fillColor.g && b === fillColor.b) {
        return;
    }

    // this pixel is part of the original black image--don't fill
    if (matchstrokeColor(r, g, b, a)) {
        return;
    }

    // execute the floodfill
    floodFill(startX, startY, r, g, b);

    // put the colorized data back on the canvas
    context.clearRect(0, 0, canvasWidth, canvasHeight);
    context.putImageData(fillData, 0, 0);
    context.drawImage(img, 0, 0);
}

// create a random color object {red,green,blue}
function randomColorRGB() {
    var hex = Math.floor(Math.random() * 16777215).toString(16);
    //var r = parseInt(hex.substring(0, 2), 16);

    var r = 155;
    var g = 155;
    var b = 255;

    //var g = parseInt(hex.substring(2, 4), 16);
    //var b = parseInt(hex.substring(4, 6), 16);
    return ({
        r: r,
        g: g,
        b: b
    });
}

// draw the image to the canvas and get its pixel array
// listen for mouse clicks and do floodfill when clicked
function start() {

    context.drawImage(img, 0, 0);
    strokeData = context.getImageData(0, 0, canvasWidth, canvasHeight);
    context.clearRect(0, 0, context.canvas.width, context.canvas.height);
    fillData = context.getImageData(0, 0, canvasWidth, canvasHeight);
    context.drawImage(img, 0, 0);

    $('#canvas').mousedown(function (e) {
        // Mouse down location
        var mouseX = parseInt(e.clientX - offsetX);
        var mouseY = parseInt(e.clientY - offsetY);
        // set a new random fillColor
        fillColor = randomColorRGB();
        // floodfill
        paintAt(mouseX, mouseY);
    });
function matchstrokeColor(r, g, b, a) {
    // never recolor the initial black divider strokes
    // must check for near black because of anti-aliasing
    return (r + g + b < 100 && a === 155);
}
// A small threshold would make it fill closer to stroke.
var strokeThreshold = 1;
function matchstrokeColor(r, g, b, a) { 
    // Use sqrt difference to decide its storke or not.
    var diffr = r - strokeColor.r;
    var diffg = g - strokeColor.g;
    var diffb= b - strokeColor.b;
    var diff = Math.sqrt(diffr * diffr + diffg * diffg + diffb * diffb) / 3;
    return (diff < strokeThreshold);
}