- <code class="language-html"><html>
- <head>
- <style type="text/css">
- form, input { 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>