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


Posted in Javascript onAugust 18, 2015

使用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在Web页面上处理图像的技巧

CamanJS Javascript库 Web页面 图像处理

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

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

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

Javascript 相关文章推荐
解决iframe的frameborder在chrome/ff/ie下的差异
Aug 12 Javascript
Jquery实现由下向上展开效果的例子
Dec 08 Javascript
轻松实现jquery手风琴效果
Jan 14 Javascript
JS组件系列之Bootstrap table表格组件神器【终结篇】
May 10 Javascript
JS监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法
Aug 05 Javascript
微信小程序 两种为对象属性赋值的方式详解
Feb 23 Javascript
Vue 2.x教程之基础API
Mar 06 Javascript
Angular2中select用法之设置默认值与事件详解
May 07 Javascript
vue 2.0封装model组件的方法
Aug 03 Javascript
解决Jquery下拉框数据动态获取的问题
Jan 25 jQuery
vue使用@scroll监听滚动事件时,@scroll无效问题的解决方法详解
Oct 15 Javascript
微信小程序仿通讯录功能
Apr 09 Javascript
JS实现下拉菜单赋值到文本框的方法
Aug 18 #Javascript
JS实现可调整倒计时间代码分享
Aug 18 #Javascript
DOM事件阶段以及事件捕获与事件冒泡先后执行顺序(图文详解)
Aug 18 #Javascript
js实现带有介绍的Select列表菜单实例
Aug 18 #Javascript
jQuery垂直多级导航菜单代码分享
Aug 18 #Javascript
js简单实现表单中点击按钮动态增加输入框数量的方法
Aug 18 #Javascript
js实现的简单radio背景颜色选择器代码
Aug 18 #Javascript
You might like
Yii列表定义与使用分页方法小结(3种方法)
2016/07/15 PHP
Javascript跨域请求的4种解决方式
2013/03/17 Javascript
javascript中常用编程知识
2013/04/08 Javascript
javascript从右边截取指定字符串的三种实现方法
2013/11/29 Javascript
jQuery 无限级菜单的简单实例
2014/02/21 Javascript
jQuery滚动条插件nanoscroller使用指南
2015/04/21 Javascript
JS实现来回出现文字的状态栏特效代码
2015/10/31 Javascript
js获取当前页的URL与window.location.href简单方法
2017/02/13 Javascript
jQuery实现IE输入框完成placeholder标签功能的方法
2017/09/20 jQuery
Vue源码学习之初始化模块init.js解析
2017/11/02 Javascript
JS实现读取xml内容并输出到div中的方法示例
2018/04/19 Javascript
简述vue状态管理模式之vuex
2018/08/29 Javascript
vue实现短信验证码登录功能(流程详解)
2019/12/10 Javascript
微信小程序实现选择地址省市区三级联动
2020/06/21 Javascript
javascript实现多边形碰撞检测
2020/10/24 Javascript
举例讲解Python中的list列表数据结构用法
2016/03/12 Python
浅谈python日志的配置文件路径问题
2018/04/28 Python
python实现月食效果实例代码
2019/06/18 Python
Python使用sklearn库实现的各种分类算法简单应用小结
2019/07/04 Python
django使用haystack调用Elasticsearch实现索引搜索
2019/07/24 Python
python读取tif图片时保留其16bit的编码格式实例
2020/01/13 Python
TensorBoard 计算图的查看方式
2020/02/15 Python
Python爬虫实现HTTP网络请求多种实现方式
2020/06/19 Python
基于python实现ROC曲线绘制广场解析
2020/06/28 Python
Python 如何创建一个简单的REST接口
2020/07/30 Python
使用Python Tkinter实现剪刀石头布小游戏功能
2020/10/23 Python
paramiko使用tail实时获取服务器的日志输出详解
2020/12/06 Python
css3中用animation的steps属性制作帧动画
2019/04/25 HTML / CSS
耐克奥地利官网:Nike奥地利
2019/08/16 全球购物
您的时尚,您的生活方式:DTLR Villa
2019/12/25 全球购物
技校生自我鉴定范文
2013/09/26 职场文书
铁路个人事迹材料
2014/01/30 职场文书
优秀员工获奖感言
2014/03/01 职场文书
严以律己专题学习研讨会发言材料
2015/11/09 职场文书
美甲店的创业计划书模板
2019/08/23 职场文书
利用python实时刷新基金估值(摸鱼小工具)
2021/09/15 Python