使用CamanJS在Web页面上处理图像的技巧

你可能会想问既然CSS已经有现成的功能可以支持基础的图像操作了,为什么我们还会想要为此使用一个像这样的 JavaScript 库呢。

好吧,除了有浏览器的支持,使用 CamanJS 有许多的好处。它为我们操作图像提供了更多的过滤器和选项。你可以在你的图像中创建高级过滤器,进而控制其中的每一个像素。你可以使用其内置的混合模式和图层系统。而它也能让你进行图像的跨域操作,并可以对操作产生的图像进行保存。

现在,就让我们来开始探索 CamanJS 所提供的特性吧!

引入必要的文件

要开始使用 CamanJS,需要简单的将这个库引入到你的页面中. 我所引用的这个最小化的 CDN 版本除了核心功能之外,所有的插件都被组合到了一个文件中:

<script src="https://cdnjs.cloudflare.com/ajax/libs/camanjs/4.1.2/caman.full.min.js">
</script>

从版本3到4,CamanJS 函数的语法发生了一点小小的改变。因此请确保在跟随这个教程进行实际操作时,你所引入的版本在4以上。

通过HTML属性进行图像操作

CamanJS 可以被用来利用 data-caman 属性对图像进行操作。如下代码向你展示了如何将一个亮度为“10”的过滤器,以及一个对比度为“30”的过滤器应用到一张图片上:

<img data-caman="brightness(10) contrast(30)"
   src="yourimage.jpg" alt="CamanJS Javascript库 Web页面 图像处理">

其它可以用类似的语法加以运用的 18 个过滤器也被打包到了这个库里面。

例如:

<img data-caman="love() hazyDays()"
   src="yourimage.jpg" alt="CamanJS Javascript库 Web页面 图像处理">

通过 JavaScript 操作图像

你也可以选择通过写几行 JavaScript 来操作一张图像。使用 JavaScript 操作的结果跟使用 data-caman 属性所产生的结果是一样的。

Caman('#your-image-id', function () {
 this.brightness(40);
 this.contrast(-10);
 this.sinCity();
 this.render();
});

实现一个图像编辑器中的控件

过滤器其实不需要做过多的调整就可以用在按钮点击的触发上. 一些像 vintage(),lomo(), 以及 sinCity() 这样的过滤器不需要参数。其它像 contrast() 和 noise() 过滤器则需要一个整型值作为参数。这个值决定了过滤器的强度。

复杂的过滤器如 tiltShift(),posterize(), 以及 vignette() 则需要不止一个参数。下面的代码块演示了如果用3个按钮进行3种过滤器操作。针对其它的过滤器也可以像这样写代码。

下面是HTML:

<canvas id="canvas"></canvas>
<button id="vintagebtn">Vintage</button>
<button id="noisebtn">Noise</button>
<button id="tiltshiftbtn">Tilt Shift</button>

下面是将过滤器应用到按钮点击上的 JavaScript/jQuery 代码:

var vintage = $('#vintagebtn');
var noise = $('#noisebtn');
var tiltshift = $('#tiltshiftbtn');
  vintage.on('click', function(e) {
 Caman('#canvas', img, function() {
  this.vintage();
  this.render();
 });
});
  noise.on('click', function(e) {
 Caman('#canvas', img, function() {
  this.noise(10);
  this.render();
 });
});
  tiltshift.on('click', function(e) {
 Caman('#canvas', img, function() {
  this.tiltShift({
   angle: 90,
   focusWidth: 600
  }).render();
 });
});

tiltshift() 也接受另外的像 startRadius radius 这样的参数, Factor.vignette() sizestrength 这两个参数,你可以参考 CamanJS 文档 来深入理解所有的过滤器。

实现滑块控件

brightness, contrast, 和 hue 这样需要相对更精确控制取值的过滤器,使用范围值输入滑块就可以很好的工作。你将会看到,实现滑块控件只比按钮控制有稍微的不同. 你可以使用下面的HTML来创建范围滑块:

<form id="silderInput">
   <label for="hue">Hue</label>
 <input id="hue" name="hue" type="range" min="0" max="300" value="0">
   <label for="contrast">Contrast</label>
 <input id="contrast" name="contrast" type="range" min="-20" max="20" value="0">
</form>

下面的jQuery代码块处理所有了操作:

$('input[type=range]').change(applyFilters);
  function applyFilters() {
 var hue = parseInt($('#hue').val());
 var cntrst = parseInt($('#contrast').val());
    Caman('#canvas', 'image.jpg', function() {
   this.revert(false);
   this.hue(hue);
   this.contrast(cntrst);
   this.render();
  });
}

applyFilters() 函数在输入范围滑块的值发生改变时都会被调用。这个函数用对应变量存储了所有范围滑块的值。为了对图像进行编辑,这些值随后会被作为参数传递到对应的过滤器。

每次我都会在应用这些过滤器时调用this.revet(false),来时的canvas回到其原来的状态。使用revert可以确保过滤器所操作的是原来的图像,而它们的效果不会是混乱的. 传入的false参数值可以避免在图像还原过程中的间断闪烁。

值得一提的另外一个细节是即使我一次只改变了它们其中的一个值,我也会将所有的过滤器应用一遍。 这是因为用户不会希望在他们正调整色相和亮度值时看到对比度被重置。

在 CamanJS 中创建定制的过滤器

这个库的许多其它特性中有一个很酷的特性就是,你可以通过创建你自己的过滤器和插件来对它进行扩展. 有两种方法可以来创建定制的过滤器。你可以用对应的值来组合内置的过滤器,或者也可以从头开始创建你自己的过滤器。

下面是创建你自己的过滤器的 jQuery 代码:

Caman.Filter.register('oldpaper', function() {
 this.pinhole();
 this.noise(10);
 this.orangePeel();
 this.render();
});

要从头开始创建过滤器,你需要一些额外的工作,这都是因为存在几个bug,你可以在 GitHub 资源库的开放问题板块 读到有关这个的内容。

图层和混合模式

除了过滤器,CamanJS 还带来了一个高级的图层系统。这个东西给了你更多的图形操作能力和选择。不想 Photoshop 中的图层,CamanJS 中的层可以嵌套。它使用混合模式来将层应用到他们的上级嵌套层。默认是一般的混合模式。CamanJS 总共有十种混合模式,包含有像 叠加(multiply), 排除(exclusion), 和 覆盖(overlay)这些常用的。

如下是使用图层和混合模式创建一个定制过滤器的jQuery代码:

Caman.Filter.register('greenTint', function() {
 this.brightness(-10);
   this.newLayer(function() {
  this.setBlendingMode("overlay");
  this.opacity(100);
  this.fillColor('#689900');
  this.filter.brightness(15);
  this.filter.contrast(10);
 });
   this.render();
});

过滤器同时被应用到原来的图层和新图层. 此外,你可以为新的图层设置其它一些像不透明度(opacity) 和 混合模式 这样的属性. 我已经用一个固定的颜色来填充了这一图层,不过你也可以通过调用 this.overlayImage('image.jpg') 来用另外一张图片对它进行填充.

操作跨域图像

如果你需要管理位于不用域名底下的图像,你可以使用 CamanJS 一并提供了的 PHP 代理。为了能使用这个特性,你需要在你的服务器上面放置这个 PHP 脚本 . 该脚本将作为代理向你的浏览器提供来自远程数据源的图像数据,以规避编辑限制。之后你需要在你的JavaScript中添加下面这一行:


Caman.remoteProxy = Caman.IO.useProxy('php');


保存编辑后的图像

CamanJS 内置了编辑后保存图像的机制。使用目前的实现,对 this.save(png) 的调用会打开一个文件下载的弹出框,而你将需要对文件重新命名,并添加一个png或者jpg的扩展名. 这是因为在调用这个函数时,浏览器会将图像的编码重定向到 base64,而它们不知道文件的类型. 下面给出的代码块会保存图片:

this.render(function () {
 this.save('png');
}); 

 Demo 跟完整代码

你可以看一下这个应用了所有特性的图像编辑器样例,截图如下:

 

CamanJS Javascript库 Web页面 图像处理

作为练习,你可以尝试改善下用户体验,如标记下当前图片上应用的滤镜或修改下保存按钮来避免需要重命名的问题。

就像我们看到的, CamanJS 是一个非常有用的图片操作库,带有很多滤镜,还有不断发展中的功能,而本教程仅仅讲述了一个皮毛。

以上内容比较长,但是介绍的都很详细,耐心阅读,对学习使用CamanJS在Web页面上处理图像很有帮助。