千万级流量H5应用涉及到的技能点-图片篇

浏览:1382 发布日期:2016/05/01 分类:技术分享 关键字: 图片存储 图片服务器配置 文件上传 前端压缩
在我们日常工作中会碰到很多图片处理业务,如图片上传,图片压缩,图片存储、缩略图等,今天给大家分享在H5应用中和图片处理相关的常用技术点。本文所采用的example如果不能下载 请访问

http://www.imwinlion.com/archives/158

假设我们有这么一个场景,母亲节来啦,客户需要一个晒图的h5小应用,每个用户只要晒一张母亲的图,写上一句对母亲的祝福,分享到朋友圈,就能获得一次抽奖的机会。

那这个H5小应用有哪些技术点和难点呢?

1、关于JS前端图片压缩

这个场景的难点在于图片压缩,为什么是图片预处理呢?首先,因为当前用户基本上是大屏手机,一个图1-4M,是很正常的,但是用户参与活动的时候,未必愿意花这个流量,这样这个活动关上传图片这一步,就会降低很多用户参与的欲望了。其次,用户的网络状态未必很好,虽然用户3G很普遍,4G成规模,WIFI热点也很多,但是上传这么大的一张图,以2M估算,每秒上传速度100KB,也要20秒,难保这20秒时间网络不出任何差错。再次,用户未必愿意等待这么长的时间。解决方案在哪里?,答案是前端压缩,这里笔者常用的插件是lrz下载地址如下,也给个demo,<!--引入必要的dom-->
<div style="text-align: center" style="backgroud:url(http://weixin.hunankeji.com/static/apps/lovemomo/img/online.png) no-repeat center">
<input type="file" id="uploadphoto" name="file" value="上传" accept="image/*" capture="camera" style="opacity: 0;height: 320px;width:320px;border: 0;"/>
</div>
<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js" ></script>
<script type="text/javascript" src="./localresizeimg/LocalResizeIMG.js"></script>
<script type="text/javascript" src="./localresizeimg/patch/mobileBUGFix.mini.js"></script>
<script>
$('#uploadphoto').localResizeIMG({
 width: 400,
 quality: 1,
 success: function (result) {
 var submitData={
 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();
 }
 });
 }
});
</script>
点击这里下载 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示意function base64toimage($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 {
listen 80;
server_name img.imwinlion.com;
index index.html index.htm index.php;
root /alidata/mnt/imwinlion;
location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.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 /empty last;
image_filter_interlace on;
image_filter_jpeg_quality 90;
image_filter resize $3 $4;
image_filter_buffer 3M;
}
location ~ .*\.(gif|jpg|JPG|PNG|GIF|BMP|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 1h;
}
access_log /dev/null;
}
本文章涉及到的相关代码会在微信公众帐号itchuangyebuluo,陆续放出,敬请关注。
http://shang.qq.com/wpa/qunwpa?idkey=7322d7b39a8564d24b48b5e7d83fcde645f4c0e9ad84f1f7ddc7baff47574d7d
最佳答案
评论( 相关
后面还有条评论,点击查看>>