使用canvas进行图像编辑的实例
程序员文章站
2022-04-29 08:32:57
前面的话
本文将分为几个小功能的形式来详细介绍canvas图像编辑
缩放
下面是一张分析图,假设默认情况下,图片和canvas宽高相同。图片的缩放(scale)范围为...
前面的话
本文将分为几个小功能的形式来详细介绍canvas图像编辑
缩放
下面是一张分析图,假设默认情况下,图片和canvas宽高相同。图片的缩放(scale)范围为0.5到3,缩放时改变的是图片的大小和图片的坐标位置
w(宽) = canvas.width * scale h(高) = canvas.height * scale x坐标 = (w - canvas.width)/2; y坐标 = (h - canvas.height)/2;
因此,代码如下
<canvas id="drawing" > <p>the canvas element is not supported!</p> </canvas> <br> <input id="scale-range" min="0.5" max="1.5" step="0.01" type="range" > <script> var drawing = document.getelementbyid('drawing'); if(drawing.getcontext){ var context = drawing.getcontext('2d'); var slider = document.getelementbyid('scale-range'); var w = 400; var h = 290; drawing.width = w; drawing.height = h; var image = new image(); image.src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/chunfen.jpg"; image.onload = function(){ drawimgbyscale(slider.value); slider.onmousemove = function(){ drawimgbyscale(slider.value); } } function drawimgbyscale(scale){ var imgw = w * scale; var imgh = h * scale; var dx =(w - imgw)/2; var dy =(h - imgh)/2; context.clearrect(0,0,w,h); context.drawimage(image,dx,dy,imgw,imgh); } } </script>
水印
利用canvas可以实现向图片添加水印的功能,先通过file控件的reader选择图片,然后使用canvas添加图片及水印,并且使用todataurl()和a标签实现添加水印后的图片的下载功能
<canvas id="drawing" > <p>the canvas element is not supported!</p> </canvas> <div> <span> <input type="file" id="addimghelper" > <button id="addimg">选择图片</button> </span> <span> <button id="addwatermark" disabled>添加水印</button> <span>水印文字为</span> <input id="watermarkwords" type="text" value="小火柴的蓝色理想"> </span> <span> <button id="downloadimg" disabled>下载图片</button> <a id="downloadimghelper" href="#" rel="external nofollow" download="带水印图片" ></a> </span> </div> <script> if(drawing.getcontext){ var cxt = drawing.getcontext('2d'); var w,h; addimg.onclick = function(){ addimghelper.click(); } addimghelper.onchange = function(){ addwatermark.disabled = true; downloadimg.disabled = true; var file = addimghelper.files[0]; if(file && /image/.test(file.type)){ var reader = new filereader(); reader.readasdataurl(file); reader.onload = function(){ var img = new image(); img.src= reader.result; img.onload = function(){ addwatermark.disabled = false; drawing.width = w = img.width; drawing.height = h = img.height; cxt.drawimage(img,0,0); addwatermark.onclick = function(){ downloadimg.disabled = false; cxt.clearrect(0,0,w,h); cxt.drawimage(img,0,0); var str = watermarkwords.value; cxt.font = "bold 50px arial"; cxt.linewidth = '1'; cxt.fillstyle = 'rgba(255,255,255,0.5)'; cxt.textbaseline = "bottom"; cxt.textalign = 'end'; cxt.filltext(str,w-10,h-10,w/2); downloadimg.onclick = function(){ downloadimghelper.href = drawing.todataurl('image/png'); downloadimghelper.click(); } } } } } } } </script>
放大镜
下面来实现一个放大镜的效果,鼠标按下并移动时,显示当前图片区域的放大效果,抬起后效果消失。放大镜效果主要使用离屏canvas的技术,离屏canvas放置的是图片的放大版,而普通canvas则放置图片的正常版
<canvas id="drawing" > <p>the canvas element is not supported!</p> </canvas> <canvas id="drawingoff" > <p>the canvas element is not supported!</p> </canvas> <script> if(drawing.getcontext){ var cxt = drawing.getcontext('2d'); var cxtoff = drawingoff.getcontext('2d'); var w,h; var scale = 1.5; var img = new image(); img.src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/chunfen.jpg"; img.onload = function(){ w = img.width; h = img.height; drawing.width = w/scale; drawing.height = h/scale; drawingoff.width = w; drawingoff.height = h; cxt.drawimage(img,0,0,w/scale,h/scale); cxtoff.drawimage(img,0,0); drawing.onmousedown = function(e){ e = e || event; var x0 = this.offsetleft; var y0 = this.offsettop; drawmagnifier(e); drawing.onmousemove = function(e){ drawmagnifier(e); } document.onmouseup = function(e){ cxt.clearrect(0,0,w/scale,h/scale); cxt.drawimage(img,0,0,w/scale,h/scale); drawing.onmousemove = null; } function drawmagnifier(e){ cxt.clearrect(0,0,w/scale,h/scale); cxt.drawimage(img,0,0,w/scale,h/scale); var x = (e.clientx-x0); var y = (e.clienty-y0); var r = 40; var dx = x - r; var dy = y - r; var sx = x*scale - r; var sy = y*scale - r; cxt.save(); cxt.beginpath(); cxt.arc(x,y,r,0,math.pi*2); cxt.linewidth = 4; cxt.strokestyle = '#069'; cxt.stroke(); cxt.clip(); cxt.drawimage(drawingoff,sx,sy,2*r,2*r,dx,dy,2*r,2*r); cxt.restore(); } } } } </script>
滤镜
下面利用canvas的getimagedata()方法,获取原始图像数据,通过对图像数据进行修改,然后输出修改后的图像数据
<canvas id="drawing1" > <p>the canvas element is not supported!</p> </canvas> <canvas id="drawing2" > <p>the canvas element is not supported!</p> </canvas> <br> <button id="nogreen">无绿色</button> <button id="noblue">无蓝色</button> <button id="togrey">灰度</button> <button id="toblackwhite">黑白</button> <button id="reverse">反色</button> <script> if(drawing1.getcontext){ var cxt1 = drawing1.getcontext('2d'); var cxt2 = drawing2.getcontext('2d'); var img = new image(); img.src="chunfen.jpg"; img.onload = function(){ cxt1.drawimage(img,0,0); function filter(fn){ var imagedata = cxt1.getimagedata(0,0,img.width,img.height); cxt2.clearrect(0,0,drawing2.width,drawing2.height); var data = imagedata.data; for(var i = 0, len = data.length; i < len; i+=4){ fn(data,i) } imagedata.data = data; cxt2.putimagedata(imagedata,0,0); } function fnnogreen(data,i){ data[i+1] = 0; } function fnnoblue(data,i){ data[i+2] = 0; } function fnreverse(data,i){ var red = data[i]; var green = data[i+1]; var blue = data[i+2]; var alpha = data[i+3]; data[i] = 255 - red; data[i+1] = 255 - green; data[i+2] = 255 - blue; } function fntogrey(data,i){ var red = data[i]; var green = data[i+1]; var blue = data[i+2]; var alpha = data[i+3]; var average = math.floor((red+green+blue)/3); data[i] = data[i+1] = data[i+2] = average; } function fntoblackwhite(data,i){ var red = data[i]; var green = data[i+1]; var blue = data[i+2]; var alpha = data[i+3]; var average = math.floor((red+green+blue)/3); if(average > 255/2){ var result = 255; }else{ var result = 0; } data[i] = data[i+1] = data[i+2] = result; } togrey.onclick = function(){ filter(fntogrey); } nogreen.onclick = function(){ filter(fnnogreen); } noblue.onclick = function(){ filter(fnnoblue); } toblackwhite.onclick = function(){ filter(fntoblackwhite); } reverse.onclick = function(){ filter(fnreverse); } } } </script>
马赛克效果
【普通模糊效果】
普通模糊效果不仅需要使用当前像素点,还需要使用周围的像素点,并把这些像素点都赋予平均值
function fntoblur(n){ cxt2.clearrect(0,0,drawing2.width,drawing2.height); var imagedata = cxt1.getimagedata(0,0,drawing2.width,drawing2.height); var tempimagedata = imagedata; var data = imagedata.data; var tempdata = tempimagedata.data; var blurr = n; var totalnum = (2*blurr + 1)*(2*blurr + 1); for(var i = blurr; i < drawing2.height - blurr; i++){ for(var j = blurr; j < drawing2.width - blurr; j++){ var totalr = 0, totalg = 0, totalb = 0; for(var dx = -blurr; dx <= blurr; dx++){ for(var dy = -blurr; dy <= blurr; dy++){ var x = i + dx; var y = j + dy; var p = x*drawing2.width + y; totalr += tempdata[p*4+0]; totalg += tempdata[p*4+1]; totalb += tempdata[p*4+2]; } } var p = i*drawing2.width + j; data[p*4+0] = totalr / totalnum; data[p*4+1] = totalg / totalnum; data[p*4+2] = totalb / totalnum; } } imagedata.data = data; cxt2.putimagedata(imagedata,0,0); }
【马赛克效果】
马赛克效果则是把一块区域的值,全部都赋予平均值
function fntomosaic(n){ cxt2.clearrect(0,0,drawing2.width,drawing2.height); var imagedata = cxt1.getimagedata(0,0,drawing2.width,drawing2.height); var tempimagedata = imagedata; var data = imagedata.data; var tempdata = tempimagedata.data; var size = n; var totalnum = size*size; for(var i = 0; i < drawing2.height; i+=size){ for(var j = 0; j < drawing2.width; j+=size){ var totalr = 0, totalg = 0, totalb = 0; for(var dx = 0; dx < size; dx++){ for(var dy = 0; dy < size; dy++){ var x = i + dx; var y = j + dy; var p = x*drawing2.width + y; totalr += tempdata[p*4+0]; totalg += tempdata[p*4+1]; totalb += tempdata[p*4+2]; } } var p = i*drawing2.width + j; var resr = totalr / totalnum; var resg = totalg / totalnum; var resb = totalb / totalnum; for(var dx = 0; dx < size; dx++){ for(var dy = 0; dy < size; dy++){ var x = i + dx; var y = j + dy; var p = x*drawing2.width + y; data[p*4+0]= resr; data[p*4+1]= resg; data[p*4+2]= resb; } } } } imagedata.data = data; cxt2.putimagedata(imagedata,0,0); }
下面是一个实例
<canvas id="drawing1" > <p>the canvas element is not supported!</p> </canvas> <canvas id="drawing2" > <p>the canvas element is not supported!</p> </canvas> <br> <button id="tolightblur">轻度模糊</button> <button id="toheavyblur">重度模糊</button> <button id="tolightmosaic">轻度马赛克</button> <button id="toheavymosaic">重度马赛克</button> <script> if(drawing1.getcontext){ var cxt1 = drawing1.getcontext('2d'); var cxt2 = drawing2.getcontext('2d'); var img = new image(); img.src="chunfen.jpg"; img.onload = function(){ cxt1.drawimage(img,0,0); tolightblur.onclick = function(){ fntoblur(1); } toheavyblur.onclick = function(){ fntoblur(3); } tolightmosaic.onclick = function(){ fntomosaic(4); } toheavymosaic.onclick = function(){ fntomosaic(9); } function fntoblur(n){ cxt2.clearrect(0,0,drawing2.width,drawing2.height); var imagedata = cxt1.getimagedata(0,0,drawing2.width,drawing2.height); var tempimagedata = imagedata; var data = imagedata.data; var tempdata = tempimagedata.data; var blurr = n; var totalnum = (2*blurr + 1)*(2*blurr + 1); for(var i = blurr; i < drawing2.height - blurr; i++){ for(var j = blurr; j < drawing2.width - blurr; j++){ var totalr = 0, totalg = 0, totalb = 0; for(var dx = -blurr; dx <= blurr; dx++){ for(var dy = -blurr; dy <= blurr; dy++){ var x = i + dx; var y = j + dy; var p = x*drawing2.width + y; totalr += tempdata[p*4+0]; totalg += tempdata[p*4+1]; totalb += tempdata[p*4+2]; } } var p = i*drawing2.width + j; data[p*4+0] = totalr / totalnum; data[p*4+1] = totalg / totalnum; data[p*4+2] = totalb / totalnum; } } imagedata.data = data; cxt2.putimagedata(imagedata,0,0); } function fntomosaic(n){ cxt2.clearrect(0,0,drawing2.width,drawing2.height); var imagedata = cxt1.getimagedata(0,0,drawing2.width,drawing2.height); var tempimagedata = imagedata; var data = imagedata.data; var tempdata = tempimagedata.data; var size = n; var totalnum = size*size; for(var i = 0; i < drawing2.height; i+=size){ for(var j = 0; j < drawing2.width; j+=size){ var totalr = 0, totalg = 0, totalb = 0; for(var dx = 0; dx < size; dx++){ for(var dy = 0; dy < size; dy++){ var x = i + dx; var y = j + dy; var p = x*drawing2.width + y; totalr += tempdata[p*4+0]; totalg += tempdata[p*4+1]; totalb += tempdata[p*4+2]; } } var p = i*drawing2.width + j; var resr = totalr / totalnum; var resg = totalg / totalnum; var resb = totalb / totalnum; for(var dx = 0; dx < size; dx++){ for(var dy = 0; dy < size; dy++){ var x = i + dx; var y = j + dy; var p = x*drawing2.width + y; data[p*4+0]= resr; data[p*4+1]= resg; data[p*4+2]= resb; } } } } imagedata.data = data; cxt2.putimagedata(imagedata,0,0); } } } </script>
以上这篇使用canvas进行图像编辑的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
上一篇: js禁止表单重复提交
下一篇: javascript实现文字无缝滚动效果