今天和大家分享一个国外的图片上传插件,这个插件支持分片上传大文件。其中著名的七牛云平台的jssdk就使用了puupload插件,可见这个插件还是相当牛叉的。

这个插件不仅仅支持图片上传,还支持大多数文件的上传,例如视频文件,音频文件,word文件等等,而且大文件都采用分片上传的机制。

Plupload有以下功能和特点:

1、拥有多种上传方式:HTML5、flash、silverlight以及传统的<input type=”file” />。Plupload会自动侦测当前的环境,选择最合适的上传方式,并且会优先使用HTML5的方式。所以你完全不用去操心当前的浏览器支持哪些上传方式,Plupload会自动为你选择最合适的方式。

2、支持以拖拽的方式来选取要上传的文件

3、支持在前端压缩图片,即在图片文件还未上传之前就对它进行压缩

4、可以直接读取原生的文件数据,这样的好处就是例如可以在图片文件还未上传之前就能把它显示在页面上预览

5、支持把大文件切割成小片进行上传,因为有些浏览器对很大的文件比如几G的一些文件无法上传。

下面就介绍一个tp5整合plupload图片上传插件的小案例,希望给大家带来一点小帮助。

一、案例目录结构

二、Index.php控制器方法

  1. <?php
  2. namespace app\index\controller;
  3. use think\Controller;
  4. use think\Db;
  5. class Index extends Controller{
  6. public function index(){
  7. $rootUrl = $this->request->root(true); //ROOT域名
  8. $rootUrl = explode('index.php',$rootUrl)[0];
  9. //模板资源变量分配
  10. foreach (config('TMPL_PARSE_STRING') as $key => $value) {
  11. $this->view->assign('_'.$key,$rootUrl.$value);
  12. }
  13. return $this->fetch();
  14. }
  15.  
  16. //图片上传方法
  17. public function upload_images(){
  18. if($this->request->isPost()){
  19. //接收参数
  20. $images = $this->request->file('file');
  21.  
  22. //计算md5和sha1散列值,TODO::作用避免文件重复上传
  23. $md5 = $images->hash('md5');
  24. $sha1= $images->hash('sha1');
  25.  
  26. //判断图片文件是否已经上传
  27. $img = Db::name('picture')->where(['md5'=>$md5,'sha1'=>$sha1])->find();//我这里是将图片存入数据库,防止重复上传
  28. if(!empty($img)){
  29. return json(['status'=>1,'msg'=>'上传成功','data'=>['img_id'=>$img['id'],'img_url'=>$this->request->root(true).'/'.$img['path']]]);
  30. }else{
  31. // 移动到框架应用根目录/public/uploads/picture/目录下
  32. $imgPath = 'public' . DS . 'uploads' . DS . 'picture';
  33. $info = $images->move(ROOT_PATH . $imgPath);
  34. $path = 'public/uploads/picture/'.date('Ymd',time()).'/'.$info->getFilename();
  35. $data = [
  36. 'path' => $path ,
  37. 'md5' => $md5 ,
  38. 'sha1' => $sha1 ,
  39. 'status' => 1 ,
  40. 'create_time' => time() ,
  41. ];
  42. if($img_id=Db::name('picture')->insertGetId($data)){
  43. return json(['status'=>1,'msg'=>'上传成功','data'=>['img_id'=>$img_id,'img_url'=>$this->request->root(true).'/'.$path]]);
  44. }else{
  45. return json(['status'=>0,'msg'=>'写入数据库失败']);
  46. }
  47. }
  48. }else{
  49. return ['status'=>0,'msg'=>'非法请求!'];
  50. }
  51. }
  52. }

三、index.html页面

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>tp5+plupload图片上传</title>
  6. </head>
  7. <body>
  8. <!-- production -->
  9. <!--<script type="text/javascript" src="./plupload.full.min.js"></script>-->
  10.  
  11. <!-- debug-->
  12. <script type="text/javascript" src="{$_plupload}/moxie.js"></script>
  13. <script type="text/javascript" src="{$_plupload}/plupload.dev.js"></script>
  14. <script type="text/javascript" src="{$_plupload}/jquery.min.js"></script>
  15. <style>
  16. ul{
  17. list-style:none;
  18. }
  19. #file-list {overflow: hidden;padding-left: initial;}
  20. #file-list li {
  21. width:160px;
  22. float: left;
  23. height:200px;
  24. position: relative;
  25. height: inherit;
  26. margin-bottom: inherit;
  27. }
  28. #file-list li a {
  29. width:150px;
  30. height:150px;
  31. text-align: center;
  32. display: flex;
  33. align-items: center;
  34. justify-content: center;
  35. margin:0 auto;
  36. border:1px solid #ccc;
  37. padding: 5px 5px 5px 5px;
  38. }
  39. .close{
  40. background-image: url("{$_plupload}/close.png");
  41. width: 30px;
  42. height: 30px;
  43. background-size: contain;
  44. position: absolute;
  45. right: 2%;
  46. top: 0;
  47. }
  48. #file-list li a img {max-width:100%;max-height: 100%;}
  49. .progress{
  50. position: absolute;
  51. background-color: rgba(4, 4, 4, 0.53);
  52. color: #fff;
  53. padding: 3px 3px 3px 3px;
  54. border-radius: 10%;
  55. }
  56. </style>
  57. <input type="hidden" id="images_upload" name="images" value=""/>
  58. <div id="container">
  59. <button class="btn btn-primary" type="button" id="pickfiles" style="height: 30px;line-height: 8px;">选择图片</button>
  60. <button class="btn btn-primary" type="button" id="uploadfiles" style="display: none">开始上传</button>
  61. <ul id="file-list">
  62. </ul>
  63. </div>
  64. <script type="text/javascript">
  65.  
  66. //调用例子
  67. var uploader = new plupload.Uploader({
  68. runtimes : 'html5,flash,silverlight,html4',//上传方式顺序优先级
  69. browse_button : 'pickfiles',//选择图片按钮id
  70. container: document.getElementById('container'),//容器
  71. url : "{:url('Index/upload_images')}",//服务器接口地址
  72. flash_swf_url : "{$_plupload}/Moxie.swf",
  73. silverlight_xap_url : "{$_plupload}/Moxie.xap",
  74. multi_selection: true,//false为单图上传,true为多图上传
  75. filters : {
  76. max_file_size : '100mb',//限制文件上传大小
  77. mime_types: [
  78. {title : "Image files", extensions : "jpg,gif,png"},//限制文件上传格式
  79. ]
  80. },
  81. init: {
  82. //init事件发生后触发
  83. PostInit: function() {
  84. //document.getElementById('filelist').innerHTML = '';
  85. document.getElementById('uploadfiles').onclick = function() {
  86. uploader.start();
  87. return false;
  88. };
  89. },
  90. FilesAdded: function(up, files) {//文件选择之后的触发的方法
  91. var len = len = files.length;
  92. for(var i = 0; i<len; i++){
  93. var file_name = files[i].name; //文件名
  94. var file_size = files[i].size;//文件大小
  95. //构造html来更新UI
  96. //var html = '<li id="file-' + files[i].id +'"><p class="file-name">' + file_name + '(' + plupload.formatSize(file_size) + ')' + '</p><p class="progress"></p></li>';
  97. var html = '<li id="file-' + files[i].id +'"><span class="close"></span></li>';
  98. $(html).appendTo('#file-list');
  99. !function(i){
  100. previewImage(files[i],function(imgsrc){
  101. $('#file-'+files[i].id).append('<a><img src="'+ imgsrc +'" /><span class="progress">12</span></a>');
  102. })
  103. }(i);
  104. $("#uploadfiles").trigger('click');
  105. }
  106. /*plupload.each(files, function(file) {
  107. document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';
  108. });*/
  109. },
  110.  
  111. UploadProgress: function(up, file) {//上传过程中调用的方法
  112. //document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
  113. $('#file-'+file.id +" .progress").html(file.percent + "%");
  114. },
  115. FileUploaded : function (up,file,res) {//文件上传完成后
  116. console.log(res.response);
  117. var data = JSON.parse(res.response).data;
  118. $('#file-'+file.id).children('.close').attr('img_id',data.img_id);
  119. var img = $("#images_upload");
  120. var str = img.val();
  121. if(str == ''){
  122. str = data.img_id;
  123. }else{
  124. str += ','+data.img_id;
  125. }
  126. img.val(str);
  127. },
  128. Error: function(up, err) {
  129. //document.getElementById('console').appendChild(document.createTextNode("\nError #" + err.code + ": " + err.message));
  130. }
  131. }
  132. });
  133.  
  134. //plupload中为我们提供了mOxie对象
  135. //有关mOxie的介绍和说明请看:https://github.com/moxiecode/moxie/wiki/API
  136. //file为plupload事件监听函数参数中的file对象,callback为预览图片准备完成的回调函数
  137. function previewImage(file,callback){
  138. if(!file || !/image\//.test(file.type)) return; //确保文件是图片
  139. if(file.type=='image/gif'){ //gif使用FileReader进行预览,因为mOxie.Image只支持jpg和png
  140. var gif = new moxie.file.FileReader();
  141. gif.onload = function(){
  142. callback(gif.result);
  143. gif.destroy();
  144. gif = null;
  145. };
  146. gif.readAsDataURL(file.getSource());
  147. }else{
  148. var image = new moxie.image.Image();
  149. image.onload = function() {
  150. image.downsize( 150, 150 );//先压缩一下要预览的图片,宽300,高300
  151. var imgsrc = image.type=='image/jpeg' ? image.getAsDataURL('image/jpeg',80) : image.getAsDataURL(); //得到图片src,实质为一个base64编码的数据
  152. callback && callback(imgsrc); //callback传入的参数为预览图片的url
  153. image.destroy();
  154. image = null;
  155. };
  156. image.load( file.getSource() );
  157. }
  158. }
  159.  
  160. uploader.init();
  161.  
  162. //移除图片
  163. $("#file-list").on('click',".close",function(){
  164. var img_id = $(this).attr("img_id");
  165. var img = $("#images_upload");
  166. var items=img.val().split(",");
  167. var index = items.indexOf(img_id);
  168. items.splice(index,1);//删除元素
  169. img.val(items.join(','));
  170. $(this).parent().remove();
  171. });
  172. </script>
  173. </body>
  174. </html>

  

如果想研究插件源码的朋友,可以看这个文件,其中大部分都已经注释了。

最终效果就是这样了。

如果对tp5不太熟悉的朋友,建议直接配置虚拟域名,将项目目录绑定到/tp5/public/目录。

案例源码:https://github.com/BlueSimle/thinkphp5-plupload (如果对你有帮助,请给个star哦。如果有什么疑问,请留言)

Thinkphp5+plupload图片上传功能,支持实时预览图片。的更多相关文章

  1. js基础进阶--图片上传时实现本地预览功能的原理

    欢迎访问我的个人博客:http://www.xiaolongwu.cn 前言 最近在项目上加一个图片裁剪上传的功能,用的是cropper插件,注意到选择本地图片后就会有预览效果,这里整理一下这种预览效 ...

  2. JavaScript实现本地图片上传前进行裁剪预览

    本项目支持IE8+,测试环境IE8,IE9,IE10,IE11,Chrome,FireFox测试通过 另:本项目并不支持Vue,React等,也不建议,引入JQuery和Vue.React本身提倡的开 ...

  3. html + js 实现图片上传,压缩,预览及图片压缩后得到Blob对象继续上传问题

    先上效果 上传图片后(设置了最多上传3张图片,三张后上传按钮消失) 点击图片放大,可以使用删除和旋转按钮 (旋转功能主要是因为ios手机拍照后上传会有写图片被自动旋转,通过旋转功能可以调正) html ...

  4. jq实现上传头像并实时预览功能

    效果 页面结构 <form action="" name="form0" id="form0"> <input type= ...

  5. thinkphp达到UploadFile.class.php图片上传功能

    片上传在站点里是非经常常使用的功能.ThinkPHP里也有自带的图片上传类(UploadFile.class.php) 和图片模型类(Image.class.php).方便于我们去实现图片上传功能,以 ...

  6. PHP语言学习之php做图片上传功能

    本文主要向大家介绍了PHP语言学习之php做图片上传功能,通过具体的内容向大家展示,希望对大家学习php语言有所帮助. 今天来做一个图片上传功能的插件,首先做一个html文件:text.php < ...

  7. vue 图片上传功能

    这次做了vue页面的图片上传功能,不带裁剪功能的! 首先是html代码,在input框上添加change事件,如下:   <ul class="clearfix">   ...

  8. 前端丨如何使用 tcb-js-sdk 实现图片上传功能

    前言 tcb-js-sdk 让开发者可以在网页端使用 JavaScript 代码服务访问云开发的服务,以轻松构建自己的公众号页面或者独立的网站等 Web 服务.本文将以实现图片上传功能为例,介绍 tc ...

  9. 分享一个react 图片上传组件 支持OSS 七牛云

    react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 排序等功能 需要 react 版本大于 v ...

随机推荐

  1. 【BZOJ3796】Mushroom追妹纸 二分+hash

    [BZOJ3796]Mushroom追妹纸 Description Mushroom最近看上了一个漂亮妹纸.他选择一种非常经典的手段来表达自己的心意——写情书.考虑到自己的表达能力,Mushroom决 ...

  2. EasyNVR H5无插件摄像机直播解决方案前端解析之:videojs的使用

    video.js的基本使用方法 一.videojs的初始化加载 videojs初始化加载分为两中 1.标签式加载 在引入videojs加载文件的前提下,可以在video标签中添加属性值"da ...

  3. EasyPlayer_Android RTSP安卓播放器直播画面卡在第一帧问题修复

    最近发现某些Android安卓手机在运行EasyPlayer播放视频时,会停留在第一帧画面,虽然有码率预示着接收端没有问题,但是画面却卡着不动. 一般来讲,这个现象有三种原因导致: 没有接收到视频帧; ...

  4. cordova 插件创建

    peng@PENG-PC /E/_My_File_____/_work/MyCode/myCode/cordova-workspace/plugman-test/ABCD $ npm install ...

  5. sap 图标查看

    showicon这个程序很不错,可以显示SAP里所有的ICON(图标). 用事务码SE38直接运行程序:showicon 即可. 显示列表之后,双击任何一个图标可以显示出每一个图标的详细信息.

  6. spring 获取bean的几种方式

    1.读取xml文件的方式,这种在初学入门的时候比较适用 . ApplicationContext applicationContext = new ClassPathXmlApplicationCon ...

  7. 4.1 《锋利的jQuery》jQuery中的事件

    $(document).ready()方法和window.onload方法的区别 事件绑定 合成事件 事件冒泡 事件对象的属性 tip1:停止事件冒泡和阻止默认行为都可以用return false替代 ...

  8. P3968 [TJOI2014]电源插排

    P3968 [TJOI2014]电源插排 线段树维护最长空区间及左端点位置,这个和$nlongn$的动态最大子序和差不多,就不多解释了 $n$较大哈希优化空间 My complete code: #i ...

  9. gVIM+zencoding快速开发HTML/CSS/JS(适用WEB前端)

    一.真正解决了UTF-8中文乱码的各种问题(菜单乱码,内容乱码,提示信息乱码),不用担心WIN用默认编码写的东西在Linux乱码,或在Linux(zh_CN.UTF-8时)写的东西在WIN下乱码.在A ...

  10. 转载h5问题总结

    判断微信浏览器 function isWeixin(){ var ua = navigator.userAgent.toLowerCase(); if(ua.match(/MicroMessenger ...