这次给大家带来canvas怎么编辑操作图像,canvas编辑操作图像的注意事项有哪些,下面就是实战案例,一起来看一下。
本次文章将分为几个小功能的形式来详细介绍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>
<p>
<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>
</p>
<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>
相信看了本文案例你已经掌握了方法,更多精彩请关注其它相关文章!
推荐阅读:
js发布者订阅者模式使用详解
node.js操作音视频文件进行加密
以上就是canvas怎么编辑操作图像的详细内容。