由于实习的工作要用javascript进行图形处理,所以这一段时间我学习了一下CamanJS这个js图形处理库,对这个库也有了大致的了解。把我对CamanJS的一些理解记录下来,便于理解和与人交流。
CamanJS官网:http://camanjs.com/
CamanJS是用JavaScript写成的一个图形处理库,它既可以node.js里边工作也可以在浏览器里边工作。它主要针对的是HTML5里边的画布元素来进行操作。CamanJS既可以写在js脚本里也可以写成HTML标签的一个属性。它有很多内置的函数可以用,也可以注册自己写的新函数来扩展它的功能。但是这些内置的函数和自己写的新函数都有一个共同点:这个函数应用于图像的每个像素上,操作某个像素时,只能访问该像素的数据(rgba),不能访问其他像素的数据。
我这里写的只是CamanJS写在js脚本文件中运行在浏览器里的情况。
下面是一个简单的CamanJS的例子
<!DOCTYPE HTML>
<HTML>
<head>
<title>CamanJS Test</title>
<script type="text/javascript" src="dist/caman.full.js"></script>
</head>
<body>
<h1>CamanJS Test</h1>
<p>
Left is origin image, right is processed by brightness function
</p>
<img id="kobe_img" src="kobe.jpg" width="500" height="400" />
<canvas id="kobe_canvas" width="500" height="400"></canvas>
<script type="text/javascript">
//draw an image on canvas
var image = document.getElementById("kobe_img");
var c = document.getElementById("kobe_canvas");
var cxt = c.getContext("2d");
cxt.drawImage(image,0,0,500,400);
//process the image on canvas
Caman("#kobe_canvas",image,function(){
this.brightness(30).render();
});
</script>
</body>
</HTML>
结果如下所示:HTML头部分引用的外部js文件是CamanJS库,body部分的js代码首先在画布上画左边的图像,然后再用CamanJS库中的brightness函数处理左边的图像再装载到画布上。这么做看起来有点画蛇添足,为什么不直接把左边的图像处理好了再直接画上去呢?其实在CamanJS的文档中,Caman("#canvas_id","path_to_image",process_func")这个函数就是想实现这么个意思(#canvas_id和path_to_image也可以是DOM对象),但是至少我用的4.1.1版本没有正确实现,如果想用这个函数就要先在画布上画点东西才行,这就是上边我写的代码。当然,如果画布上画的图像正是我们要处理的图像,也可以用Caman("#canvas_id",process_func);这个函数来处理。brightness函数的作用是调整图像的亮度,我们发现处理后两幅图像的亮度确实发生了变化。
CamanJS的基本用法就是
Caman('#canvas_id','image_id', function () {
this.brightness(10);
this.contrast(30);
this.sepia(60);
...//other process steps
this.render();
});
CamanJS还有其他的类似于PS中的图层的用法,就我用的4.1.1版本来看,CamanJS所有的操作都是写在Caman这个函数里面的,把要操作的画布和图像对象/id传进去,然后传进去一个不带参数的函数,然后就完了。它的图像处理函数主要是一些内置的函数,像brightness,grayscale等等,具体有哪些,它们是什么意思,怎么用参见官网http://camanjs.com/guides/#BuiltIn。当然,我们也可以自己定义一些处理函数,注册它们,然后像这些内置函数一样使用。注册的方法如下:
Caman.Filter.register("filtername",function(para){
...//pre calculate, done immediately
return this.process("filtername", function(rgba){
.../pixel wise operater, operate on each pixel
return rgba;
});
});
注册的函数有个限制,就是你的函数只能对单个像素点进行操作。当然,它的内置函数也是每次对单个像素点进行操作的。处理的时候CamanJS把这个函数对每个像素点运行一遍。CamanJS确实有一个访问像素的类PixelInfo,但是这个类并没有对我们开放,如果你想用它的话,必须要自己修改CamanJS的源脚本,把这个类导出来。并且这个类的坐标系很奇怪。它获得像素点的方式也是通过和画布对象的交互来获得的,并且仅就我用的4.1.1的版本来说,这个类的代码是错的,根本就不能获得像素。所以,如果想获得像素的数据,还不如自己直接从画布对象那里获得,没必要绕一个圈子,并且这圈子还是个错的。
总结一下,CamanJS的优势是它的用法比较简单,我们能很方便的将一些简单的每次只处理单个像素的程序实现在图像上。随之而来的它的劣势就是,对于像素级别的操作它不能很好的支持,所以如果我们每次要操作多个像素,比如求个梯度,那还是别用这个了。