在我们日常工作中会碰到很多图片处理业务,如图片上传,图片压缩,图片存储、缩略图等,今天给大家分享在H5应用中和图片处理相关的常用技术点。本文所采用的example如果不能下载 请访问
http://www.imwinlion.com/archives/158
假设我们有这么一个场景,母亲节来啦,客户需要一个晒图的h5小应用,每个用户只要晒一张母亲的图,写上一句对母亲的祝福,分享到朋友圈,就能获得一次抽奖的机会。
那这个H5小应用有哪些技术点和难点呢?
1、关于JS前端图片压缩
这个场景的难点在于图片压缩,为什么是图片预处理呢?首先,因为当前用户基本上是大屏手机,一个图1-4M,是很正常的,但是用户参与活动的时候,未必愿意花这个流量,这样这个活动关上传图片这一步,就会降低很多用户参与的欲望了。其次,用户的网络状态未必很好,虽然用户3G很普遍,4G成规模,WIFI热点也很多,但是上传这么大的一张图,以2M估算,每秒上传速度100KB,也要20秒,难保这20秒时间网络不出任何差错。再次,用户未必愿意等待这么长的时间。解决方案在哪里?,答案是前端压缩,这里笔者常用的插件是lrz下载地址如下,也给个demo,
$('#uploadphoto').localResizeIMG({
width:400,
quality:1,
success:function(result){
varsubmitData={
data:result.clearBase64,
};
$('.loading').show();
$("#prevImg").attr("src",result.base64);
$.ajax({
type:"POST",
url:"{:U('Album/uploadb64',array('id'=>$appid))}",
data:submitData,
dataType:"json",
success:function(data){
$("#prevImg").attr("src",data.url);
$('#imgurl').val(data.url);
$('.loading').hide();
},
complete:function(XMLHttpRequest,textStatus){
$('.loading').hide();
},
error:function(XMLHttpRequest,textStatus,errorThrown){//上传失败
alert("额,出错了,请上报给管理员吧");
$('.loading').hide();
}
});
}
});
复制代码点击这里下载 localresizeimg,如果不能下载,请访问http://www.imwinlion.com/archives/158
2、关于图片异步上传
用户在提交图片的时候,我们需要好的用户体念,必须要使用异步上传插件,这里百度一下,有很多,但一般太重,引入的文件太多,笔者推荐自己写的 jquery.attach.js,3KB,功能强大,文档见
jquery.attach.js,简单好用的文件上传插件
http://www.imwinlion.com/archives/143
3、关于base64图片存储问题
一般图片在前端通过JS压缩后,会以base65的格式存储起来,然后上传到后端,那么后端怎么进行存储呢?这里用php示意functionbase64toimage($strBase64,$dstPath){
$ifp=fopen($dstPath,"wb");
fwrite($ifp,base64_decode($strBase64));
fclose($ifp);
return($dstPath);
}
复制代码其中$strbase64是前端通过lzrz控件传递过来的base64字符串,$dstPath 是文件存储的目标路径
如果自己用jquery ajax 异步上传base64文件需要注意,因为jquey 会把其中特殊的几个字符转码掉,因此最好用urlencode 处理掉再通过ajax 传输,后端用urldecode解码后再处理base64 内容
4、如何设计图片文件存储的名称和路径策略
这个问题的实质是如何设计上节 的$dstPath问题。是为什么会有这个问题呢?笔者在日常开发种发现很多图片存储无设计, 所以的到的图片大概是这样的
http://www.imwinlion.com/wp-content/uploads/2016/04/新建图像-300×300.png
像这种图片结构,在应用根目录下新建一个upload 文件夹,然后下面分日期/uploads/2016/04/ 在小型的应用中,还能将就着用的,但是一旦图片数目多起来,并且要存储的是图片的id时,我们该怎么做呢?笔者研读阿里的 fastfs,并经过大量的应用实践,积累了一套实用好操作的图片命名策略,如下
[hostid][level][dirstr][filename][suffix]
这种名称策略怎么理解呢?
hostid:图片服务器资源ID.这个涉及到我们自身的服务器资源规划问题。自定义的,比如我们应用占用了俩台服务器资源,一台是应用服务器,我们编号为0,一台是资源服务器,我们将这个服务器资源编号为1,这个数据就是hostid
level:相对于图片服务根目录来说,图片存储的文件夹目录深度,一般为俩层。比如我们存储的根目录为 /mnt/h5app/,那么这下面 的 目录 a/b/c,level就是3
dirstr:目录字符串,如上,目录字符串就是abc
filename: md5 策略或者uuid 策略生成 的文件名,如md5(microtime() . mt_rand(1000,9999));
suffix:文件的后缀,如.jpg,.png
举个列子。假设我们的应用服务器服务器,编号是0,根目录是/alidata/www/www.imwinlion.com/ ,对应的域名是www.imwinlion.com
我们的图片服务器有三台,一台编号是1,目录是/mnt/www.imwinlion.com/ ,对应的域名是res1.imwinlion.com
另一台编号是2,根目录是/mnt/www.imwinlion.cn/,对应的域名是res2.imwinlion.com
现在,我们根据我们设计的文件存储策略,假设名称是13abc01f9c76ce5c45aeec2e6f816c95b854b.jpg,那么根据问价夹的第1位数字,知道这个文件hostid 是1,
应该存放在编号为1的服务器,也就是/mnt/www.imwinlion.com/ 下
根据第二个参数level 为3,我们知道这个文件有3个父级子目录,那么接下来的三个字母abc 就是dirstr , 接下来的01f9c76ce5c45aeec2e6f816c95b854b 是md5 生成的随机字符串
最后.jpg 是文件格式,那么这个文件的存储路径应该是这样
/mnt/www.imwinlion.com/a/b/c/13abc01f9c76ce5c45aeec2e6f816c95b854b.jpg
对应访问地址是这样 http://res1.imwinlion.com/a/b/c/13abc01f9c76ce5c45aeec2e6f816c95b854b.jpg,文件id 就是文件名称 13abc01f9c76ce5c45aeec2e6f816c95b854b.jpg
我们数据库存这个id ,前端只要根据策略和这个ID就能够获得 图片路径
这种策略的核心在于先根据业务逻辑规划出图片存放路径。是先知道了文件路径,然后再存储。但是我们常用的框架,把文件的命名策略封闭起来了,我们只能先存起来,再获得文件名。这需要改造!!
5、图片的服务器端自动缩略图
服务器端自动缩略图机制有很多,有应用自动缩略图,比如php我们可以选择 timthumb.php 。 点击下面下载
timthumb 如果不能下载,请访问http://www.imwinlion.com/archives/158
采用该机制需要注意 ,132 行左右
你需要把你的 域名添加到$ALLOWED_SITES 数组中,// If ALLOW_EXTERNAL is true and ALLOW_ALL_EXTERNAL_SITES is false, then external images will only be fetched from these domains and their subdomains.
if(!isset($ALLOWED_SITES)){
$ALLOWED_SITES=array(‘youhost.com’,’imwinlion.com’);
}
复制代码
笔者采用的是另外一种。自建nginx 图片服务器,安装image_filter 模块
server{
listen80;
server_name img.imwinlion.com;
index index.html index.htm index.php;
root/alidata/mnt/imwinlion;
location~.*\.(php|php5)?$
{
fastcgi_pass127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
location~(.*)\.(gif|jpg|jpeg|png|PNG|JPG|JPEG)\!(\d+)x(\d+)$
{
try_files $1.$2/emptylast;
image_filter_interlace on;
image_filter_jpeg_quality90;
image_filter resize $3 $4;
image_filter_buffer3M;
}
location~.*\.(gif|jpg|JPG|PNG|GIF|BMP|jpeg|png|bmp|swf)$
{
expires30d;
}
location~.*\.(js|css)?$
{
expires1h;
}
access_log/dev/null;
}
推荐一下本人目前正在写的一本书
互联网入门级编码人员,设计师,产品经理,系统后端工程师,DBA,以及想懂一点点技术的老板--你们可以把这本书买回去,送给和你一起创业兄弟们。
本书地址 http://yuedu.baidu.com/ebook/977275a5767f5acfa0c7cd55
部分目录如下,本人微信号betaniao,加我请写 简叔推荐