转《canvas实现滤镜效果》
- <code class="language-html"><html>
- <head>
- <style type="text/css">
- form, input {width: 73px;height: 27px;}
- form {
- position: relative;
- float: left;
- margin: 0 10px 0 0;
- }
- #up-button{
- position: absolute;
- right: 0;
- top: 0;
- cursor: pointer;
- opacity: 0;
- filter: alpha(opacity=0);
- outline: none;
- }
- #button{
- }
- iframe {display: none;}
- </style>
- </head>
- <body>
- <div class="bt">
- <form id="uf">
- <input type="file" name="file" id="up-button"/>
- <input type="button" id="button" value="upload"/>
- <input type="button" id="download" value="download"/>
- </form>
- <span><input type="radio" value="spread" id="spread" name="filter"/><label for="spread">油画效果</label></span>
- <span><input type="radio" id="gray" name="filter"/><label for="gray">灰度效果</label></span>
- <span><input type="radio" id="comic" name="filter"/><label for="comic">连环画效果</label></span>
- <span><input type="radio" id="old" name="filter"/><label for="old">怀旧效果</label></span>
- <span><input type="radio" id="negatives" name="filter"/><label for="negatives">底片效果</label></span>
- <span><input type="radio" id="black" name="filter"/><label for="black">黑白效果</label></span>
- <span><input type="radio" id="cameo" name="filter"/><label for="cameo">浮雕效果</label></span>
- </div>
- <br>
- <canvas id="cv">fuck ie</canvas>
- <canvas id="myCanvas" >Gray Filter</canvas>
- <script>
- /**
- * 获取mimeType
- * @param {String} type the old mime-type
- * @return the new mime-type
- */
- var _fixType = function(type) {
- type = type.toLowerCase().replace(/jpg/i, 'jpeg');
- var r = type.match(/png|jpeg|bmp|gif/)[0];
- return 'image/' + r;
- };
- /**
- * 在本地进行文件保存
- * @param {String} data 要保存到本地的图片数据
- * @param {String} filename 文件名
- */
- var saveFile = function(data, filename){
- var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
- save_link.href = data;
- save_link.download = filename;
- var event = document.createEvent('MouseEvents');
- event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
- save_link.dispatchEvent(event);
- };
- document.getElementById("download").onclick=function()
- {
- //图片导出为 png 格式
- var type = 'png';
- var imgData = canvas.toDataURL(type);
- // 加工image data,替换mime type
- imgData = imgData.replace(_fixType(type),'image/octet-stream');
- // 下载后的问题名
- var filename = 'bloglaotou_' + (new Date()).getTime() + '.' + type;
- // download
- saveFile(imgData,filename);
- }
- // 1.灰度效果
- //计算公式 .299 * r + .587 * g + .114 * b;
- // calculate gray scale value
- function gray(canvasData)
- {
- for ( var x = 0; x < canvasData.width; x++) {
- for ( var y = 0; y < canvasData.height; y++) {
- // Index of the pixel in the array
- var idx = (x + y * canvasData.width) * 4;
- var r = canvasData.data[idx + 0];
- var g = canvasData.data[idx + 1];
- var b = canvasData.data[idx + 2];
- var gray = .299 * r + .587 * g + .114 * b;
- // assign gray scale value
- canvasData.data[idx + 0] = gray; // Red channel
- canvasData.data[idx + 1] = gray; // Green channel
- canvasData.data[idx + 2] = gray; // Blue channel
- canvasData.data[idx + 3] = 255; // Alpha channel
- // add black border
- if(x < 8 || y < 8 || x > (canvasData.width - 8) || y > (canvasData.height - 8))
- {
- canvasData.data[idx + 0] = 0;
- canvasData.data[idx + 1] = 0;
- canvasData.data[idx + 2] = 0;
- }
- }
- }
- return canvasData;
- }
- //2.怀旧效果
- function old(canvasData)
- {
- for ( var x = 0; x < canvasData.width; x++) {
- for ( var y = 0; y < canvasData.height; y++) {
- // Index of the pixel in the array
- var idx = (x + y * canvasData.width) * 4;
- var r = canvasData.data[idx + 0];
- var g = canvasData.data[idx + 1];
- var b = canvasData.data[idx + 2];
- var dr=.393*r+.769*g+.189*b;
- var dg=.349*r+.686*g+.168*b;
- var db=.272*r+.534*g+.131*b;
- var scale=Math.random()*0.5 + 0.5;
- var fr=scale*dr+(1-scale)*r;
- scale=Math.random()*0.5 + 0.5;
- var fg=scale*dg+(1-scale)*g;
- scale=Math.random()*0.5 + 0.5;
- var fb=scale*db+(1-scale)*b;
- canvasData.data[idx + 0] = fr; // Red channel
- canvasData.data[idx + 1] = fg; // Green channel
- canvasData.data[idx + 2] = fb; // Blue channel
- canvasData.data[idx + 3] = 255; // Alpha channel
- // add black border
- if(x < 8 || y < 8 || x > (canvasData.width - 8) || y > (canvasData.height - 8))
- {
- canvasData.data[idx + 0] = 0;
- canvasData.data[idx + 1] = 0;
- canvasData.data[idx + 2] = 0;
- }
- }
- }
- return canvasData;
- }
- //3 底片效果
- //算法原理:将当前像素点的RGB值分别与255之差后的值作为当前点的RGB值,即
- //R = 255 – R;G = 255 – G;B = 255 – B;
- function negatives(canvasData)
- {
- for ( var x = 0; x < canvasData.width; x++) {
- for ( var y = 0; y < canvasData.height; y++) {
- // Index of the pixel in the array
- var idx = (x + y * canvasData.width) * 4;
- var r = canvasData.data[idx + 0];
- var g = canvasData.data[idx + 1];
- var b = canvasData.data[idx + 2];
- var fr=255-r;
- var fg=255-g;
- var fb=255-b;
- canvasData.data[idx + 0] = fr; // Red channel
- canvasData.data[idx + 1] = fg; // Green channel
- canvasData.data[idx + 2] = fb; // Blue channel
- canvasData.data[idx + 3] = 255; // Alpha channel
- // add black border
- if(x < 8 || y < 8 || x > (canvasData.width - 8) || y > (canvasData.height - 8))
- {
- canvasData.data[idx + 0] = 0;
- canvasData.data[idx + 1] = 0;
- canvasData.data[idx + 2] = 0;
- }
- }
- }
- return canvasData;
- }
- //4 黑白效果
- //求RGB平均值Avg = (R + G + B) / 3,如果Avg >= 100,则新的颜色值为R=G=B=255;
- //如果Avg < 100,则新的颜色值为R=G=B=0;255就是白色,0就是黑色;
- //至于为什么用100作比较,这是一个经验值吧,设置为128也可以,可以根据效果来调整。
- function black(canvasData)
- {
- for ( var x = 0; x < canvasData.width; x++) {
- for ( var y = 0; y < canvasData.height; y++) {
- // Index of the pixel in the array
- var idx = (x + y * canvasData.width) * 4;
- var r = canvasData.data[idx + 0];
- var g = canvasData.data[idx + 1];
- var b = canvasData.data[idx + 2];
- if((r+g+b)>=300)
- {
- fr=fg=fb=255;
- }
- else
- {
- fr=fg=fb=0;
- }
- canvasData.data[idx + 0] = fr; // Red channel
- canvasData.data[idx + 1] = fg; // Green channel
- canvasData.data[idx + 2] = fb; // Blue channel
- canvasData.data[idx + 3] = 255; // Alpha channel
- // add black border
- if(x < 8 || y < 8 || x > (canvasData.width - 8) || y > (canvasData.height - 8))
- {
- canvasData.data[idx + 0] = 0;
- canvasData.data[idx + 1] = 0;
- canvasData.data[idx + 2] = 0;
- }
- }
- }
- return canvasData;
- }
- //5 浮雕效果
- //用相邻点的RGB值减去当前点的RGB值并加上128作为新的RGB值。
- //由于图片中相邻点的颜色值是比较接近的,因此这样的算法处理之后,只有颜色的边沿区域,
- //也就是相邻颜色差异较大的部分的结果才会比较明显,而其他平滑区域则值都接近128左右,
- //也就是灰色,这样就具有了浮雕效果。
- //在实际的效果中,这样处理后,有些区域可能还是会有”彩色”的一些点或者条状痕迹,所以最好再对新的RGB值做一个灰度处理。
- function cameo(canvasData)
- {
- for ( var x = 0; x < canvasData.width; x++) {
- for ( var y = 0; y < canvasData.height; y++) {
- // Index of the pixel in the array
- var idx = (x + y * canvasData.width) * 4;
- var r = canvasData.data[idx + 0];
- var g = canvasData.data[idx + 1];
- var b = canvasData.data[idx + 2];
- var idx2 = (x + (y+1) * canvasData.width) * 4;
- var r2 = canvasData.data[idx2 + 0];
- var g2 = canvasData.data[idx2 + 1];
- var b2 = canvasData.data[idx2 + 2];
- var fr=r2-r+128;
- var fg=g2-g+128;
- var fb=b2-b+128;
- var gray = .299 * fr + .587 * fg + .114 * fb;
- canvasData.data[idx + 0] = gray; // Red channel
- canvasData.data[idx + 1] = gray; // Green channel
- canvasData.data[idx + 2] = gray; // Blue channel
- canvasData.data[idx + 3] = 255; // Alpha channel
- // add black border
- if(x < 8 || y < 8 || x > (canvasData.width - 8) || y > (canvasData.height - 8))
- {
- canvasData.data[idx + 0] = 0;
- canvasData.data[idx + 1] = 0;
- canvasData.data[idx + 2] = 0;
- }
- }
- }
- return canvasData;
- }
- //6.连环画效果
- //连环画的效果与图像灰度化后的效果相似,它们都是灰度图,但连环画增大了图像的对比度,使整体明暗效果更强.
- //算法:
- //R = |g – b + g + r| * r / 256
- //G = |b – g + b + r| * r / 256;
- //B = |b – g + b + r| * g / 256;
- function comic(canvasData)
- {
- for ( var x = 0; x < canvasData.width; x++) {
- for ( var y = 0; y < canvasData.height; y++) {
- // Index of the pixel in the array
- var idx = (x + y * canvasData.width) * 4;
- var r = canvasData.data[idx + 0];
- var g = canvasData.data[idx + 1];
- var b = canvasData.data[idx + 2];
- var fr=Math.abs((g-r+g+b))*r/256;
- var fg=Math.abs((b-r+g+b))*r/256;
- var fb=Math.abs((b-r+g+b))*g/256;
- //var fr=(g-r+g+b)*r/256;
- //var fg=(b-r+g+b)*r/256;
- //var fb=(b-r+g+b)*g/256;
- canvasData.data[idx + 0] = fr; // Red channel
- canvasData.data[idx + 1] = fg; // Green channel
- canvasData.data[idx + 2] = fb; // Blue channel
- canvasData.data[idx + 3] = 255; // Alpha channel
- // add black border
- if(x < 8 || y < 8 || x > (canvasData.width - 8) || y > (canvasData.height - 8))
- {
- canvasData.data[idx + 0] = 0;
- canvasData.data[idx + 1] = 0;
- canvasData.data[idx + 2] = 0;
- }
- }
- }
- return canvasData;
- }
- //9 扩散(毛玻璃)
- //原理:用当前点四周一定范围内任意一点的颜色来替代当前点颜色,最常用的是随机的采用相邻点进行替代。
- function spread(canvasData)
- {
- for ( var x = 0; x < canvasData.width; x++) {
- for ( var y = 0; y < canvasData.height; y++) {
- // Index of the pixel in the array
- var idx = (x + y * canvasData.width) * 4;
- var r = canvasData.data[idx + 0];
- var g = canvasData.data[idx + 1];
- var b = canvasData.data[idx + 2];
- var rand=Math.floor(Math.random()*10)%3;
- var idx2 = (x+rand + (y+rand) * canvasData.width) * 4;
- var r2 = canvasData.data[idx2 + 0];
- var g2 = canvasData.data[idx2 + 1];
- var b2 = canvasData.data[idx2 + 2];
- var fr=r2;
- var fg=g2;
- var fb=b2;
- canvasData.data[idx + 0] = fr; // Red channel
- canvasData.data[idx + 1] = fg; // Green channel
- canvasData.data[idx + 2] = fb; // Blue channel
- canvasData.data[idx + 3] = 255; // Alpha channel
- // add black border
- if(x < 8 || y < 8 || x > (canvasData.width - 8) || y > (canvasData.height - 8))
- {
- canvasData.data[idx + 0] = 0;
- canvasData.data[idx + 1] = 0;
- canvasData.data[idx + 2] = 0;
- }
- }
- }
- return canvasData;
- }
- var cv = document.getElementById('cv');
- var c = cv.getContext('2d');
- var canvas = document.getElementById("myCanvas");
- var context = canvas.getContext("2d");
- var fileBtn = document.getElementById("up-button");
- var img = new Image();
- fileBtn.onchange = getImg;
- function init() {
- cv.width = img.width;
- cv.height = img.height;
- c.drawImage(img, 0, 0);
- var f="";
- var filter = document.getElementsByName("filter");
- for(i=0;i<filter.length;i++)
- {
- if(filter[i].checked)
- {
- f=filter[i].id;
- }
- }
- switch(f){
- case "gray":setGray();break;
- case "spread":setSpread();break;
- case "comic":setComic();break;
- case "old":setOld();break;
- case "negatives":setNegatives();break;
- case "black":setBlack();break;
- case "cameo":setCameo();break;
- case "casting":setCasting();break;
- case "frozen":setFrozen();break;
- default:setGray();break;
- }
- };
- function getImg(file) {
- var reader = new FileReader();
- reader.readAsDataURL(fileBtn.files[0]);
- reader.onload = function () {
- img.src = reader.result;
- }
- }
- window.onload = function() {
- img.src = 'http://bbs.blueidea.com/forum.php?mod=attachment&aid=MjEyMzA1fDJiYzQxZThkfDEzODMxMDU2NDd8NjU2ODk5fDMxMDU1MTQ%3D';
- img.onload = init
- // re-size the canvas deminsion
- canvas.width = img.width;
- canvas.height = img.height;
- // get 2D render object
- var context = canvas.getContext("2d");
- context.drawImage(img, 0, 0);
- var canvasData = context.getImageData(0, 0, canvas.width, canvas.height);
- canvasData=gray(canvasData);
- // canvasData=spread(canvasData);
- // canvasData=old(canvasData);
- // canvasData=frozen(canvasData);
- // canvasData=casting(canvasData);
- // canvasData=cameo(canvasData);
- // canvasData=comic(canvasData);
- // canvasData=black(canvasData);
- // canvasData=negatives(canvasData);
- context.putImageData(canvasData, 0, 0); // at coords 0,0
- };
- document.getElementById('spread').onclick=setSpread;
- function setSpread()
- {
- canvas.width = img.width;
- canvas.height = img.height;
- var context = canvas.getContext("2d");
- context.drawImage(img, 0, 0);
- var canvasData = context.getImageData(0, 0, canvas.width, canvas.height);
- canvasData=spread(canvasData);
- context.putImageData(canvasData, 0, 0); // at coords 0,0
- }
- document.getElementById('gray').onclick=setGray;
- function setGray()
- {
- canvas.width = img.width;
- canvas.height = img.height;
- var context = canvas.getContext("2d");
- context.drawImage(img, 0, 0);
- var canvasData = context.getImageData(0, 0, canvas.width, canvas.height);
- canvasData=gray(canvasData);
- context.putImageData(canvasData, 0, 0); // at coords 0,0
- }
- document.getElementById('old').onclick=setOld;
- function setOld()
- {
- canvas.width = img.width;
- canvas.height = img.height;
- var context = canvas.getContext("2d");
- context.drawImage(img, 0, 0);
- var canvasData = context.getImageData(0, 0, canvas.width, canvas.height);
- canvasData=old(canvasData);
- context.putImageData(canvasData, 0, 0); // at coords 0,0
- }
- document.getElementById('cameo').onclick=setCameo;
- function setCameo()
- {
- canvas.width = img.width;
- canvas.height = img.height;
- var context = canvas.getContext("2d");
- context.drawImage(img, 0, 0);
- var canvasData = context.getImageData(0, 0, canvas.width, canvas.height);
- canvasData=cameo(canvasData);
- context.putImageData(canvasData, 0, 0); // at coords 0,0
- }
- document.getElementById('comic').onclick=setComic;
- function setComic()
- {
- canvas.width = img.width;
- canvas.height = img.height;
- var context = canvas.getContext("2d");
- context.drawImage(img, 0, 0);
- var canvasData = context.getImageData(0, 0, canvas.width, canvas.height);
- canvasData=comic(canvasData);
- context.putImageData(canvasData, 0, 0); // at coords 0,0
- }
- document.getElementById('black').onclick=setBlack;
- function setBlack()
- {
- canvas.width = img.width;
- canvas.height = img.height;
- var context = canvas.getContext("2d");
- context.drawImage(img, 0, 0);
- var canvasData = context.getImageData(0, 0, canvas.width, canvas.height);
- canvasData=black(canvasData);
- context.putImageData(canvasData, 0, 0); // at coords 0,0
- }
- document.getElementById('negatives').onclick=setNegatives;
- function setNegatives()
- {
- canvas.width = img.width;
- canvas.height = img.height;
- var context = canvas.getContext("2d");
- context.drawImage(img, 0, 0);
- var canvasData = context.getImageData(0, 0, canvas.width, canvas.height);
- canvasData=negatives(canvasData);
- context.putImageData(canvasData, 0, 0); // at coords 0,0
- }
- </script>
- </body>
- </html></code>
转《canvas实现滤镜效果》的更多相关文章
- 转《在浏览器中使用tensorflow.js进行人脸识别的JavaScript API》
作者 | Vincent Mühle 编译 | 姗姗 出品 | 人工智能头条(公众号ID:AI_Thinker) [导读]随着深度学习方法的应用,浏览器调用人脸识别技术已经得到了更广泛的应用与提升.在 ...
- face-api.js:一个在浏览器中进行人脸识别的 JavaScript 接口
Mark! 本文将为大家介绍一个建立在「tensorflow.js」内核上的 javascript API——「face-api.js」,它实现了三种卷积神经网络架构,用于完成人脸检测.识别和特征点检 ...
- TensorFlow.js之安装与核心概念
TensorFlow.js是通过WebGL加速.基于浏览器的机器学习js框架.通过tensorflow.js,我们可以在浏览器中开发机器学习.运行现有的模型或者重新训练现有的模型. 一.安装 ...
- 在Java中直接调用js代码(转载)
http://blog.csdn.net/xzyxuanyuan/article/details/8062887 JDK1.6版添加了新的ScriptEngine类,允许用户直接执行js代码. 在Ja ...
- 第十一章:WEB浏览器中的javascript
客户端javascript涵盖在本系列的第二部分第10章,主要讲解javascript是如何在web浏览器中实现的,这些章节介绍了大量的脚本宿主对象,这些对象可以表示浏览器窗口.文档树的内容.这些章节 ...
- 在Java中直接调用js代码
JDK1.6版添加了新的ScriptEngine类,允许用户直接执行js代码. 在Java中直接调用js代码 不能调用浏览器中定义的js函数,会抛出异常提示ReferenceError: “alert ...
- TensorFlow.js入门(一)一维向量的学习
TensorFlow的介绍 TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理.Tensor(张量)意味着N维数组,Flow(流)意味着 ...
- JavaScript权威指南--WEB浏览器中的javascript
知识要点 1.客户端javascript window对象是所有客户端javascript特性和API的主要接入点.它表示web浏览器的一个窗口或窗体,并且可以用window表示来引用它.window ...
- 解决webkit浏览器中js方法中使用window.event提示未定义的问题
这实际上是一个浏览器兼容性问题,根源百度中一大堆,简要说就是ie中event对象是全局变量,所以哪里都能使用到,但是webkit内核的浏览器中却不存在这个全局变量event,而是以一个隐式的局部变量的 ...
- JS Date当前时间:获取日期时间方法在各浏览器中的差异
转自:http://www.feiesoft.com/00047/<script type="text/javascript"> // JS Date当前时间获取方法在 ...
随机推荐
- go标准库的学习-io
参考https://studygolang.com/pkgdoc 导入方式: import "io" o包提供了对I/O原语的基本接口.本包的基本任务是包装这些原语已有的实现(如o ...
- mysql中engine=innodb和engine=myisam的区别(转)
转自http://blog.csdn.net/lingyi_xu/article/details/5393791 innodb引擎和mysiam引擎的区别 引擎 事务 外键 建 ...
- 深入浅出的webpack4构建工具--webpack4+react构建环境(二十)
下面我们来配置下webpack4+react的开发环境,之前都是针对webpack4+vue的.下面我们也是在之前项目结构的基础之上进行配置下. 首先看下如下是我为 webpack4+react 基本 ...
- 原生js函数的伪重载
一.我们在学习java的时候,其中方法有一个比较的重要的特性重载,根据传入的参数的个数来执行不同的方法,而方法其根据签名来判断,而JavaScript却不能根据方法的签名来进行重载,只能通过参数的个数 ...
- SkylineGlobe 邻近度(Proximity)分析JavaScript源代码
邻近度(Proximity)描述了地理空间中两个地物距离相近的程度,是空间分析的一个重要手段. <html xmlns="http://www.w3.org/1999/xhtml&qu ...
- Luogu2045 方格取数加强版(K取方格数) 费用流
题目传送门 题意:给出一个$N \times N$的方格,每个格子中有一个数字.你可以取$K$次数,每次取数从左上角的方格开始,每一次只能向右或向下走一格,走到右下角结束,沿路的方格中的数字将会被取出 ...
- CSV文件解析
CSV(逗号分隔值文件格式) 逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和 ...
- [Spark][Python]DataFrame的左右连接例子
[Spark][Python]DataFrame的左右连接例子 $ hdfs dfs -cat people.json {"name":"Alice",&quo ...
- P1438 无聊的数列
P1438 无聊的数列 链接 分析: 等差数列可加,首项相加,公差相加. 代码: #include<cstdio> #include<algorithm> #include&l ...
- 使用 cron 定时任务实现 war 自动化发布
autoRelease.sh #!/bin/sh /home/tomcat/bin/shutdown.sh echo "tomcat stoped" cd /home/tomcat ...