php图片素描化,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为高斯模糊后的像素点。

先看看效果对比图:

2dbd1dd80f99208278bb477d12331957.png

sigma可以调节效果。

代码实例:

sigma:0.8

下载

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

gaussMatrix[i] = gaussMatrix[i] / gaussSum; // 除gaussSum是归一化

}

//console.log(gaussMatrix);

// 循环计算整个图像每个像素高斯处理之后的值

for (var x=0; x

for (var y=0; 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;

}

上面就是canvas实现图片转素描效果的全部代码,大家可以自己动手编译调试。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值