canvas教程

Javascript图像处理

字号+ 作者:H5之家 来源:H5之家 2016-09-17 10:02 我要评论( )

Javascript图像处理,思路HTML5的canvas提供了getImageData接口来获取canvas中的数据,所以我们能够先用drawImage接口将图片画在canvas上然后再通过getImageData

思路

HTML5的canvas提供了getImageData接口来获取canvas中的数据,所以我们能够先用drawImage接口将图片画在canvas上然后再通过getImageData得到图片数据矩阵。

canvas的浏览器支持情况,请参见:

需要注意,虽然IE9开始支持了canvas接口,但是其getImageData获取的数据并不是以标准的TypedArray方式存储的,或者说IE9没有提供对WebGL Native binary data的支持,所以如果需要对IE9支持,下面的矩阵需要用Array的方式保存。虽然IE9以下版本(例如IE8)有开源项目explorercanvas提供canvas支持,但很可惜G_vmlCanvasManager并没有提供位图数据获取接口。TypedArray的相关内容可以参考HTML5的新数组,TypedArray的相关支持情况可以参见:

 

基本矩阵

在图像处理中,矩阵计算是非常重要的内容,所以我们首先来建立一个矩阵模型。

通过getImageData接口获取的ImageData虽然具有类似矩阵的结构,但是他的结构是不可变的,不适合扩展,所以我们选择在Javascript中自建一个矩阵。

function Mat(__row, __col, __data, __buffer){ this.row = __row || 0; this.col = __col || 0; this.channel = 4; this.buffer = __buffer || new ArrayBuffer(__row * __col * 4); this.data = new Uint8ClampedArray(this.buffer);
__data && this.data.set(__data); this.bytes = 1; this.type = "CV_RGBA"; }

 

图片数据转成矩阵的方法 function imread(__image){ var width = __image.width, height = __image.height; iResize(width, height); iCtx.drawImage(__image, 0, 0); var imageData = iCtx.getImageData(0, 0, width, height), tempMat = new Mat(height, width, imageData.data); imageData = null; iCtx.clearRect(0, 0, width, height); return tempMat; }

注意:这里的__image指的是Image对象,不是字符串URL。因为浏览器中Image的读取是一个异步过程,并不能立刻返回相应的Mat对象,所以这个函数应当这样使用:

var img = new Image(); img.onload = function(){ var myMat = imread(img); }; img.src = "1.jpg";

iCtx和iResize方法是一个全局变量,允许给其它函数公用:

var iCanvas = document.createElement("canvas"), iCtx = iCanvas.getContext("2d"); function iResize(__width, __height){ iCanvas.width = __width; iCanvas.height = __height; }

我们来看一下drawImage方法:

用途

在canvas上绘制一个图片。

语法

context.drawImage(img,x,y);

context.drawImage(img,x,y,width,height);

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

例子

?filename=playcanvas_drawimagedy&preval=img,90,130,50,60,10,10,50,60

还有getImageData方法:

用途

获取canvas中的图像数据。

数据是以RGBA色彩空间返回的,即:

R - 红色通道大小

G - 绿色通道大小

B - 蓝色通道大小

A - 不透明程度大小

语法

context.getImageData(x,y,width,height);

例子

red = imgData.data[0]; green = imgData.data[1]; blue = imgData.data[2]; alpha = imgData.data[3];

?filename=tryhtml5_canvas_getimagedata_firstpx

 

矩阵转成图像数据的方法

经过处理后的矩阵,需要一个方法变成ImageData,然后我们就可以通过putImageData方法,在canvas上绘制经过处理的图像了。

function RGBA2ImageData(__imgMat){ var width = __imgMat.col, height = __imgMat.row, imageData = iCtx.createImageData(width, height); imageData.data.set(__imgMat.data); return imageData; }

我们来看一下putImageData方法:

用途

通过图像数据,在canvas上绘制图像。

语法

context.putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);

 

将彩色图转换成灰度图

最后我们进行一个简单的色彩空间变换,将图像从RGBA转成GRAY。

function cvtColor(__src){ if(__src.type && __src.type === "CV_RGBA"){ var row = __src.row, col = __src.col; var dst = new Mat(row, col); data = dst.data, data2 = __src.data; var pix1, pix2, pix = __src.row * __src.col * 4; while (pix){ data[pix -= 4] = data[pix1 = pix + 1] = data[pix2 = pix + 2] = (data2[pix] * 299 + data2[pix1] * 587 + data2[pix2] * 114) / 1000; data[pix + 3] = data2[pix + 3]; } }else{ return src; } return dst; }

参考OpenCV文档中的转换公式:

  RGBA to Gray: Y <- 0.299 * R + 0.587 * G + 0.114 * B

  Gray to RGBA: R <- Y, G <- Y, B <- Y, A <- 255

我们可以得出RGBA to GRAY(指的是拥有4个通道)对应映射关系应该为:

  RGBA to RGBA(GRAY): R1 = G1 = B1 <-  0.299 * R + 0.587 * G + 0.114 * B , A1 <- A

 

系列目录

Javascript图像处理系列

 

参考资料

HTML Canvas Reference

Miscellaneous Image Transformations

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Canvas动画应用

    Canvas动画应用

    2016-09-05 13:03

  • Taking Picture From Webcam Using Canvas

    Taking Picture From Webcam Using Canvas

    2016-08-30 11:00

  • JavaScript强化教程

    JavaScript强化教程

    2016-08-27 18:03

  • firefox中使用canvas画图的问题 JavaScript DHTML 脚本技术讨论

    firefox中使用canvas画图的问题 JavaScript DHTML 脚本技术讨论

    2016-08-21 11:00

网友点评