Javascript 使用HTML5画布为绘画应用程序创建逼真的铅笔工具

Javascript 使用HTML5画布为绘画应用程序创建逼真的铅笔工具,javascript,image-processing,canvas,html5-canvas,Javascript,Image Processing,Canvas,Html5 Canvas,首先我想说的是,我做了大量的研究并尝试了自己,但没有取得任何成功 我正在使用Canvas开发一个类似MSPaint的应用程序,我想创建一个铅笔工具,它看起来像手工绘制的图画一样逼真。。。下面是链接中使用默认工具的示例: 我尝试使用mousespeed和linewidth属性,但效果不好(移动鼠标时,整行会放大和缩小)。我不知道对像素原始数据起作用的算法 你知道一些现有的或适用的算法吗?非常感谢你的帮助 编辑 我决定添加我选择的解决方案,因为它似乎引起了很多人的兴趣。 因此,到目前为止,我发现最

首先我想说的是,我做了大量的研究并尝试了自己,但没有取得任何成功

我正在使用Canvas开发一个类似MSPaint的应用程序,我想创建一个铅笔工具,它看起来像手工绘制的图画一样逼真。。。下面是链接中使用默认工具的示例:

我尝试使用mousespeed和linewidth属性,但效果不好(移动鼠标时,整行会放大和缩小)。我不知道对像素原始数据起作用的算法

你知道一些现有的或适用的算法吗?非常感谢你的帮助

编辑

我决定添加我选择的解决方案,因为它似乎引起了很多人的兴趣。 因此,到目前为止,我发现最好的方法是使用此处介绍的技术在画布上绘制图像:。
它就像一个符咒,结果真的令人信服,这是很容易实施。在这里尝试一下:

您可以尝试下面的演示

您最有可能使用
moveTo
lineTo
创建路径,如果这样做,将共享路径的属性,直到您关闭路径。因此,每次更改厚度时,都需要调用
closePath
,然后再次调用
beginPath

在我的示例中,我使用绘制点。基本上,它开始画画。然后,在MouseMove上,它将当前坐标与最后一个坐标进行比较,并绘制它们之间的所有点。它还可以使用
fillRect
进行绘制。根据移动的速度,线条会变粗或变细

这是绘图功能的代码

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    painting = false,
    lastX = 0,
    lastY = 0,
    lineThickness = 1;

canvas.width = canvas.height = 600;
ctx.fillRect(0, 0, 600, 600);

canvas.onmousedown = function(e) {
    painting = true;
    ctx.fillStyle = "#ffffff";
    lastX = e.pageX - this.offsetLeft;
    lastY = e.pageY - this.offsetTop;
};

canvas.onmouseup = function(e){
    painting = false;
}

canvas.onmousemove = function(e) {
    if (painting) {
        mouseX = e.pageX - this.offsetLeft;
        mouseY = e.pageY - this.offsetTop;

        // find all points between        
        var x1 = mouseX,
            x2 = lastX,
            y1 = mouseY,
            y2 = lastY;


        var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
        if (steep){
            var x = x1;
            x1 = y1;
            y1 = x;

            var y = y2;
            y2 = x2;
            x2 = y;
        }
        if (x1 > x2) {
            var x = x1;
            x1 = x2;
            x2 = x;

            var y = y1;
            y1 = y2;
            y2 = y;
        }

        var dx = x2 - x1,
            dy = Math.abs(y2 - y1),
            error = 0,
            de = dy / dx,
            yStep = -1,
            y = y1;

        if (y1 < y2) {
            yStep = 1;
        }

        lineThickness = 5 - Math.sqrt((x2 - x1) *(x2-x1) + (y2 - y1) * (y2-y1))/10;
        if(lineThickness < 1){
            lineThickness = 1;   
        }

        for (var x = x1; x < x2; x++) {
            if (steep) {
                ctx.fillRect(y, x, lineThickness , lineThickness );
            } else {
                ctx.fillRect(x, y, lineThickness , lineThickness );
            }

            error += de;
            if (error >= 0.5) {
                y += yStep;
                error -= 1.0;
            }
        }



        lastX = mouseX;
        lastY = mouseY;

    }
}
var canvas=document.getElementById(“canvas”),
ctx=canvas.getContext(“2d”),
绘画=假,
lastX=0,
lastY=0,
线宽=1;
canvas.width=canvas.height=600;
ctx.fillRect(0,060600);
canvas.onmousedown=函数(e){
绘画=真实;
ctx.fillStyle=“#ffffff”;
lastX=e.pageX-this.offsetLeft;
lastY=e.pageY-this.offsetTop;
};
canvas.onmouseup=函数(e){
绘画=假;
}
canvas.onmousemove=函数(e){
如果(绘画){
mouseX=e.pageX-this.offsetLeft;
mouseY=e.pageY-this.offsetTop;
//找出所有点之间的距离
var x1=鼠标,
x2=lastX,
y1=老鼠,
y2=整形术;
var陡峭=(数学abs(y2-y1)>数学abs(x2-x1));
如果(陡峭){
var x=x1;
x1=y1;
y1=x;
变量y=y2;
y2=x2;
x2=y;
}
如果(x1>x2){
var x=x1;
x1=x2;
x2=x;
变量y=y1;
y1=y2;
y2=y;
}
变量dx=x2-x1,
dy=数学绝对值(y2-y1),
错误=0,
de=dy/dx,
yStep=-1,
y=y1;
if(y1=0.5){
y+=yStep;
误差-=1.0;
}
}
lastX=鼠标;
拉蒂=老鼠;
}
}

@Loktar我尝试使用jquery mobile实现同样的事情。我可以获得touchevents,但无法划定界限。你能帮忙吗?谢谢:)我很难弄明白这是怎么回事。我意识到这很容易看到。有选择地切换出:
if(陡峭){
if(x1>x2){
,也做
else if(x1>x2){
(用于实验),也切换
if(y1
您将直观地看到算法在做什么。我想让您知道,您已经在互联网上创建了一个感觉最好的铅笔工具(比许多有绘图工具的网站要好得多)。哇@汤姆帕克,我真的很感激!也许我会将它包装成一个组件或其他东西,然后扔到Github上。