本章给大家介绍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为高斯模糊后的像素点。

先看看效果对比图:

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

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实现图片转素描效果的全部代码,大家可以自己动手编译调试。

标签
DT素材网

DT素材网

162

0

0

( 此人很懒并没有留下什么~~ )