制作一个类似 Instagram的图片滤镜web App(上)

原文看: http://tutorialzine.com/2013/02/instagram-filter-app/,明河扩写了下。
这篇教程会非常有意思, Instagram或美图秀秀或camera360的照片滤镜功能想必大家都完成,这篇教程将教大家使用html5的知识,实现类似功能。
源码可以到 明河的github上查看
通过这篇教程你将学到什么?
- >Filereader.js的使用,明河也会讲解到html5中 FileReader的API
- Caman.js,非常牛逼的
canvas库,用于实现图片滤镜效果 - jquery的使用
- jQuery Mousewheel的使用
请不要用过时的浏览器运行这个demo,亲们懂的…
创建一个源图片容器
#photo层用于创建一个拖拽区域和canvas容器。
从demo来看,在容器中有”拖拽一个图片到这里”的文案,但html代码中并不存在,这里我们来学习个css知识 :after伪类。
#photo:after{
content: '拖拽一个图片到这里';
top: 150px;
z-index: 1;
color: #ccc;
display: block;
font-size: 20px;
position: absolute;
width: 100%;
letter-spacing: 1px;
}
:after伪类会在容器元素内容的最后面插入指定的内容, content属性必须存在!
插入的为inline行内元素,所以这里使用了 display: block;。
给容器增加拖拽读取图片逻辑
这里需要用到名为 FileReader.js的jquery插件,FileReader.js可以实现创建一个拖拽层,并暴露出了方便读取文件数据API。
引入jquery和FileReader插件:
使用方法:
var photo = $('#photo');
//调用FileReader插件
photo.fileReaderJS({
//监听拖拽的各个事件
on:{
beforestart: function(e, file) {
// 如果你想要跳过这个文件直接 return false
},
loadstart: function(e, file) {
},
progress: function(e, file) {
},
load: function(e, file) {
},
error: function(e, file) {
},
loadend: function(e, file) {
},
abort: function(e, file) {
},
skip: function(e, file) {
// 当一个文件被跳过处理时触发
}
}
})
FileReader的 on参数非常重要,内置所有拖拽和读取文件事件,比如常用的 load事件(读取完文件后触发)。
FileReader支持的事件非常丰富,基本上可以控制整个拖拽读取文件的过程。
接下来我们利用FileReader来实现拖拽读取图片信息的功能。
var photo = $('#photo');
//调用FileReader插件
photo.fileReaderJS({
//监听拖拽的各个事件
on:{
beforestart: function(e, file) {
//只接受图片
return /^image/.test(file.type);
},
load: function(e, file) {
}
}
})
图片滤镜只能对图片起作用,所以我们需要将图片外的文件过滤掉。
beforestart: function(e, file) {
//只接受图片,通过过滤file数据中的type属性
return /^image/.test(file.type);
}
将读取图片并插入到#photo层内
load: function(e, file) {
//向拖拽容器添加一个图片元素
var img = $('
').appendTo(photo);
//图片读取成功后触发,这样才能找到图片原始宽度和高度
img.load(function(){
//...
});
// 设置图片的src,直接读取二进制图片数据
// 触发img的load事件
img.attr('src', e.target.result);
}
load事件有二个参数:
- e:事件对象,带有文件的二进制数据(base64),通过
e.target.result获得; - file:文件数据对象
在高级浏览器(IE6之类的滚粗就不说了)下图片的src是可以直接设置为base64编码的二进制数据,格式类似如下:
这是html5实现本地图片预览的核心。
(PS:css中的background-image也是支持base64编码的二进制数据。)
详细内容,明河推荐看 《base64:URL背景图片与web页面性能优化》。
img读取图片完毕会触发load事件,这是才能取到图片的原始尺寸!而且load函数请写在 src设置之前!。
接下来处理下图片尺寸过大的情况:
//图片宽度和高度
var imgWidth,imgHeight;
//图片允许的最大宽度和高度
var maxWidth = 500, maxHeight = 500;
var newHeight,newWidth;
var ratio;
//图片读取成功后触发,这样才能找到图片原始宽度和高度
img.load(function(){
imgWidth = this.width;
imgHeight = this.height;
// 控制在500*500px内
if (imgWidth >= maxWidth || imgHeight >= maxHeight) {
if (imgWidth > imgHeight) {
//ratio是希望处理图片时,依旧可以保证比例的正确
ratio = imgWidth / maxWidth;
newWidth = maxWidth;
newHeight = imgHeight / ratio;
} else {
ratio = imgHeight / maxHeight;
newHeight = maxHeight;
newWidth = imgWidth / ratio;
}
} else {
newHeight = imgHeight;
newWidth = imgWidth;
}
});
下一篇教程将完成最有意思的部分:实现图片滤镜功能。
这里先放放,来听听明河唠叨下 FileReaderJs的的原理。
FileReaderJS的原理
FileReaderJS其实是对html5对象 FileReader的封装。FileReader用于读取文件数据,在html5的异步文件上传中有广泛的应用,所以这个API非常重要,也是为什么明河要唠叨的原因,推荐大家掌握。
典型使用:
function readFile(){
//FileList中的一个文件
var file = this.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e){
result.innerHTML = '
'
}
}
readAsDataURL:核心方法,用于读取文件数据。
onload:事件,在读取文件成功后触发,通过读取result属性,可以获取到文件数据(base64编码)。
详细内容推荐大家阅读 《FileReader详解与实例—读取并显示图像文件》。
