用Canvas如何把图片转素描的效果,原理和方法是什么
Admin 2022-07-15 群英技术资讯 948 次浏览
在实际应用中,我们有时候会遇到“用Canvas如何把图片转素描的效果,原理和方法是什么”这样的问题,我们该怎样来处理呢?下文给大家介绍了解决方法,希望这篇“用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实现图片转素描效果的全部代码,大家可以自己动手编译调试。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要介绍了Ratchet 模态框的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
CSS+HTML实现登录页面的代码是什么?有不少朋友对此感兴趣,下面小编给大家整理和分享了相关知识和资料,易于大家学习和理解,有需要的朋友可以借鉴参考,下面我们一起来了解一下吧。
今天我们详细了解一下伪类选择器,希望对大家有所帮助!伪类选择器 是一种允许通过未包含在HTML元素的状态信息来定位HTML元素的用法。伪类选择器 的具体用法就是向已有的选择器增加关键字,表示定位的HTML元素的状态信息。
css利用border制作各种形状的原理如图:使用border绘制三角形是什么原理?事实上,宽度相等的border是以45度对接的,如下图: 没有了上border如图所示: 再设置border的宽度为0:设置border的高度为0:如图最后设置左右border的颜色为透明,如下图:贴代码,做个小三角形<style>.border{
这篇文章主要介绍了HTML5 3D旋转相册的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008