最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

使用canvas进行图像编辑的实例

来源:懂视网 责编:小采 时间:2020-11-27 22:31:40
文档

使用canvas进行图像编辑的实例

使用canvas进行图像编辑的实例:前面的话 本文将分为几个小功能的形式来详细介绍canvas图像编辑 缩放 下面是一张分析图,假设默认情况下,图片和canvas宽高相同。图片的缩放(scale)范围为0.5到3,缩放时改变的是图片的大小和图片的坐标位置 W(宽) = canvas.width * scal
推荐度:
导读使用canvas进行图像编辑的实例:前面的话 本文将分为几个小功能的形式来详细介绍canvas图像编辑 缩放 下面是一张分析图,假设默认情况下,图片和canvas宽高相同。图片的缩放(scale)范围为0.5到3,缩放时改变的是图片的大小和图片的坐标位置 W(宽) = canvas.width * scal

前面的话

本文将分为几个小功能的形式来详细介绍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进行图像编辑的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

使用canvas进行图像编辑的实例

使用canvas进行图像编辑的实例:前面的话 本文将分为几个小功能的形式来详细介绍canvas图像编辑 缩放 下面是一张分析图,假设默认情况下,图片和canvas宽高相同。图片的缩放(scale)范围为0.5到3,缩放时改变的是图片的大小和图片的坐标位置 W(宽) = canvas.width * scal
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top