转《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当前时间获取方法在 ...
随机推荐
- 贪心之oj.1797
1797:金银岛 查看 提交 统计 提问 总时间限制: 3000ms 内存限制: 65536kB 描述 某天KID利用飞行器飞到了一个金银岛上,上面有许多珍贵的金属,KID虽然更喜欢各种宝石的艺术品, ...
- Linux 从网卡到TCP IP协议栈数据流跟踪与审计
前沿 在学代码审计,然后最近做Linux协议栈的审计,发现Linux不愧是一个久经考验的系统,本来以为可以找到个DoS的,结果发现其在TCP/IP协议栈的链路层实现,利用了各种技术,用来提高性能与安全 ...
- FreeRTOS队列
简单来讲队列是任务间通信的方式,队列本身是可以存储消息的,队列的消息可以由一个或者多个任务写入,也可以由一个或者多个任务读出,总之消息队列是任务间通信方式:
- linux下service+命令和直接去执行命令的区别,怎么自己建立一个service启动
启动一些程序服务的时候,有时候直接去程序的bin目录下去执行命令,有时候利用service启动. 比如启动mysql服务时,大部分喜欢执行service mysqld start.当然也可以去mysq ...
- 在SpringMVC中使用HandlerInterceptor来实现拦截器功能
需求:我们需要在请求某些特定的URL(URL格式为Restful格式)时添加拦截器,以实现进行权限控制. 如:/ResourcePlan/projectCode/P1503127828/PROJECT ...
- RHEL7基本命令
Terminal TTY TTY是TeleTYpe的一个老缩写. Teletypes,或者teletypewriters,原来指的是电传打字机,是通过串行线用打印机键盘通过阅读和发送信息的东西,和古老 ...
- 懒人小工具1:winform自动生成Model,Insert,Select,Delete以及导出Excel的方法
懒人小工具2:T4自动生成Model,Insert,Select,Delete以及导出Excel的方法 github地址:https://github.com/Jimmey-Jiang/J ...
- Ceph分布式存储-原理介绍及简单部署
1)Ceph简单概述Ceph是一个分布式存储系统,诞生于2004年,最早致力于开发下一代高性能分布式文件系统的项目.Ceph源码下载:http://ceph.com/download/.随着云计算的发 ...
- 百度之星-day2-1004-二分答案
由于序列有序,求其中一个最优解,二分答案即可,注意二分时上边界满足才保存 #include<iostream> #include<stdio.h> #include<st ...
- 不重叠的线段 51nod
链接 [http://www.51nod.com/onlineJudge/questionCode.html#problemId=1133¬iceId=468024] 题意 X轴上有N条 ...