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实现图片转素描效果的全部代码,大家可以自己动手编译调试。
Atas ialah kandungan terperinci html5利用canvas实现图片转素描效果. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Panduan untuk Sempadan Jadual dalam HTML. Di sini kita membincangkan pelbagai cara untuk menentukan sempadan jadual dengan contoh Sempadan Jadual dalam HTML.

Panduan untuk HTML margin-kiri. Di sini kita membincangkan gambaran keseluruhan ringkas tentang HTML margin-left dan Contoh-contohnya bersama-sama dengan Pelaksanaan Kodnya.

Ini ialah panduan untuk Nested Table dalam HTML. Di sini kita membincangkan cara membuat jadual dalam jadual bersama-sama dengan contoh masing-masing.

Panduan untuk Susun Atur Jadual HTML. Di sini kita membincangkan Nilai Susun Atur Jadual HTML bersama-sama dengan contoh dan output n perincian.

Panduan untuk Pemegang Tempat Input HTML. Di sini kita membincangkan Contoh Pemegang Tempat Input HTML bersama-sama dengan kod dan output.

Panduan kepada Senarai Tertib HTML. Di sini kami juga membincangkan pengenalan senarai dan jenis Tertib HTML bersama-sama dengan contoh mereka masing-masing

Panduan untuk Memindahkan Teks dalam HTML. Di sini kita membincangkan pengenalan, cara teg marquee berfungsi dengan sintaks dan contoh untuk dilaksanakan.

Panduan untuk Butang onclick HTML. Di sini kita membincangkan pengenalan, kerja, contoh dan onclick Event masing-masing dalam pelbagai acara.
