您好,欢迎访问一九零五行业门户网

html5利用canvas实现图片转素描效果

本章给大家介绍html5如何利用canvas实现图片转素描效果。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。
素描滤镜原理:
最基础的算法就是:
1、去色;(去色公式:gray = 0.3 red + 0.59 green + 0.11 * blue)
2、复制去色图层,并且反色;
3、对反色图像进行高斯模糊;
4、模糊后的图像叠加模式选择颜色减淡效果。
减淡公式:c =min( a +(a×b)/(255-b),255),其中c为混合结果,a为去色后的像素点,b为高斯模糊后的像素点。
先看看效果对比图:
sigma可以调节效果。
代码实例:
<!doctype html><html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="controls"> <input type="file" name="" id="imgs" value=""/> <br /> <!--<input type="range" name="" id="range_radius" value="10" oninput="changeradius()"/> radius:<span id="value_radius">1</span> <br />--> <input type="range" name="" id="range_sigma" value="40" oninput="changesigma()"/> sigma:<span id="value_sigma">0.8</span> <br /> <a href="" download="canvas_love.png" id="save_href">下载</a> </div> <canvas id="canvas1" width="" height=""></canvas> <br> <canvas id="canvas2" width="" height=""></canvas> <script type="text/javascript"> var eleimg = document.getelementbyid("imgs"); var eleradius = document.getelementbyid("range_radius"); var elesigma = document.getelementbyid("range_sigma"); var valueradius = document.getelementbyid("value_radius"); var valuesigma = document.getelementbyid("value_sigma"); var svaehref = document.getelementbyid("save_href"); var imgsrc = "img/2.jpg"; var radius = 1; var sigma = 0.8; eleimg.addeventlistener("input",function (e) { var fileobj = e.currenttarget.files[0] if (window.filereader) { var reader = new filereader(); reader.readasdataurl(fileobj); //监听文件读取结束后事件 reader.onloadend = function (e) { imgsrc = e.target.result; //e.target.result就是最后的路径地址 sketch() }; } }); var butsave = document.getelementbyid("save"); function changeradius() { valueradius.innertext = eleradius.value/10; radius = eleradius.value/10; sketch() } function changesigma() { valuesigma.innertext = elesigma.value/50; sigma = elesigma.value/50; sketch() } var canvas1 = document.queryselector("#canvas1"); var cxt1 = canvas1.getcontext("2d"); var canvas = document.queryselector("#canvas2"); var cxt = canvas.getcontext("2d"); function sketch() { cxt1.clearrect(0,0,canvas1.width,canvas1.height); cxt.clearrect(0,0,canvas.width,canvas.height); var img = new image(); img.src = imgsrc; img.onload = function () { canvas1.width = 600; canvas1.height = (img.height/img.width)*600; cxt1.drawimage(img, 0, 0, canvas1.width, canvas1.height); canvas.width = 600; canvas.height = (img.height/img.width)*600; cxt.drawimage(img, 0, 0, canvas.width, canvas.height); var imagedata = cxt.getimagedata(0, 0, canvas.width, canvas.height); //对于 imagedata 对象中的每个像素,都存在着四方面的信息,即 rgba 值 var imagedata_length = imagedata.data.length/4;// var origindata = json.parse(json.stringify(imagedata)) // 解析之后进行算法运算 var origindata = []; for (var i = 0; i < imagedata_length; i++) { var red = imagedata.data[i*4]; var green = imagedata.data[i*4 + 1]; var blue = imagedata.data[i*4 + 2]; var gray = 0.3 * red + 0.59 * green + 0.11 * blue;//去色 origindata.push(gray) origindata.push(gray) origindata.push(gray) origindata.push(imagedata.data[i * 4 + 3]) var anti_data = 255 - gray;//取反 imagedata.data[i * 4] = anti_data; imagedata.data[i * 4 + 1] = anti_data; imagedata.data[i * 4 + 2] = anti_data; } imagedata = gaussblur(imagedata, radius, sigma)//高斯模糊 for (var i = 0; i < imagedata_length; i++) { var dodge_data = math.min((origindata[i*4] + (origindata[i*4]*imagedata.data[i * 4])/(255-imagedata.data[i * 4])), 255)//减淡 imagedata.data[i * 4] = dodge_data; imagedata.data[i * 4 + 1] = dodge_data; imagedata.data[i * 4 + 2] = dodge_data; } console.log(imagedata) cxt.putimagedata(imagedata, 0, 0); var tempsrc = canvas.todataurl("image/png"); svaehref.href=tempsrc; } } sketch() function gaussblur(imgdata, radius, sigma) { var pixes = imgdata.data, width = imgdata.width, height = imgdata.height; radius = radius || 5; sigma = sigma || radius / 3; var gaussedge = radius * 2 + 1; // 高斯矩阵的边长 var gaussmatrix = [], gausssum = 0, a = 1 / (2 * sigma * sigma * math.pi), b = -a * math.pi; for (var i=-radius; i<=radius; i++) { for (var j=-radius; j<=radius; j++) { var gxy = a * math.exp((i * i + j * j) * b); gaussmatrix.push(gxy); gausssum += gxy; // 得到高斯矩阵的和,用来归一化 } } var gaussnum = (radius + 1) * (radius + 1); for (var i=0; i<gaussnum; i++) { gaussmatrix[i] = gaussmatrix[i] / gausssum; // 除gausssum是归一化 } //console.log(gaussmatrix); // 循环计算整个图像每个像素高斯处理之后的值 for (var x=0; x<width;x++) { for (var y=0; y<height; y++) { var r = 0, g = 0, b = 0; //console.log(1); // 计算每个点的高斯处理之后的值 for (var i=-radius; i<=radius; i++) { // 处理边缘 var m = handleedge(i, x, width); for (var j=-radius; j<=radius; j++) { // 处理边缘 var mm = handleedge(j, y, height); var currentpixid = (mm * width + m) * 4; var jj = j + radius; var ii = i + radius; r += pixes[currentpixid] * gaussmatrix[jj * gaussedge + ii]; g += pixes[currentpixid + 1] * gaussmatrix[jj * gaussedge + ii]; b += pixes[currentpixid + 2] * gaussmatrix[jj * gaussedge + ii]; } } var pixid = (y * width + x) * 4; pixes[pixid] = ~~r; pixes[pixid + 1] = ~~g; pixes[pixid + 2] = ~~b; } } imgdata.data = pixes; return imgdata; } function handleedge(i, x, w) { var m = x + i; if (m < 0) { m = -m; } else if (m >= w) { m = w + i - x; } return m; } </script> </body></html>
上面就是canvas实现图片转素描效果的全部代码,大家可以自己动手编译调试。
以上就是html5利用canvas实现图片转素描效果的详细内容。
其它类似信息

推荐信息