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

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

Plupload有以下功能和特点:

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

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

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

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

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

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

一、案例目录结构

二、Index.php控制器方法

<?php
namespace app\index\controller;
use think\Controller;
use think\Db;
class Index extends Controller{
public function index(){
$rootUrl = $this->request->root(true); //ROOT域名
$rootUrl = explode('index.php',$rootUrl)[0];
//模板资源变量分配
foreach (config('TMPL_PARSE_STRING') as $key => $value) {
$this->view->assign('_'.$key,$rootUrl.$value);
}
return $this->fetch();
} //图片上传方法
public function upload_images(){
if($this->request->isPost()){
//接收参数
$images = $this->request->file('file'); //计算md5和sha1散列值,TODO::作用避免文件重复上传
$md5 = $images->hash('md5');
$sha1= $images->hash('sha1'); //判断图片文件是否已经上传
$img = Db::name('picture')->where(['md5'=>$md5,'sha1'=>$sha1])->find();//我这里是将图片存入数据库,防止重复上传
if(!empty($img)){
return json(['status'=>1,'msg'=>'上传成功','data'=>['img_id'=>$img['id'],'img_url'=>$this->request->root(true).'/'.$img['path']]]);
}else{
// 移动到框架应用根目录/public/uploads/picture/目录下
$imgPath = 'public' . DS . 'uploads' . DS . 'picture';
$info = $images->move(ROOT_PATH . $imgPath);
$path = 'public/uploads/picture/'.date('Ymd',time()).'/'.$info->getFilename();
$data = [
'path' => $path ,
'md5' => $md5 ,
'sha1' => $sha1 ,
'status' => 1 ,
'create_time' => time() ,
];
if($img_id=Db::name('picture')->insertGetId($data)){
return json(['status'=>1,'msg'=>'上传成功','data'=>['img_id'=>$img_id,'img_url'=>$this->request->root(true).'/'.$path]]);
}else{
return json(['status'=>0,'msg'=>'写入数据库失败']);
}
}
}else{
return ['status'=>0,'msg'=>'非法请求!'];
}
}
}

三、index.html页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tp5+plupload图片上传</title>
</head>
<body>
<!-- production -->
<!--<script type="text/javascript" src="./plupload.full.min.js"></script>--> <!-- debug-->
<script type="text/javascript" src="{$_plupload}/moxie.js"></script>
<script type="text/javascript" src="{$_plupload}/plupload.dev.js"></script>
<script type="text/javascript" src="{$_plupload}/jquery.min.js"></script>
<style>
ul{
list-style:none;
}
#file-list {overflow: hidden;padding-left: initial;}
#file-list li {
width:160px;
float: left;
height:200px;
position: relative;
height: inherit;
margin-bottom: inherit;
}
#file-list li a {
width:150px;
height:150px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
margin:0 auto;
border:1px solid #ccc;
padding: 5px 5px 5px 5px;
}
.close{
background-image: url("{$_plupload}/close.png");
width: 30px;
height: 30px;
background-size: contain;
position: absolute;
right: 2%;
top: 0;
}
#file-list li a img {max-width:100%;max-height: 100%;}
.progress{
position: absolute;
background-color: rgba(4, 4, 4, 0.53);
color: #fff;
padding: 3px 3px 3px 3px;
border-radius: 10%;
}
</style>
<input type="hidden" id="images_upload" name="images" value=""/>
<div id="container">
<button class="btn btn-primary" type="button" id="pickfiles" style="height: 30px;line-height: 8px;">选择图片</button>
<button class="btn btn-primary" type="button" id="uploadfiles" style="display: none">开始上传</button>
<ul id="file-list">
</ul>
</div>
<script type="text/javascript"> //调用例子
var uploader = new plupload.Uploader({
runtimes : 'html5,flash,silverlight,html4',//上传方式顺序优先级
browse_button : 'pickfiles',//选择图片按钮id
container: document.getElementById('container'),//容器
url : "{:url('Index/upload_images')}",//服务器接口地址
flash_swf_url : "{$_plupload}/Moxie.swf",
silverlight_xap_url : "{$_plupload}/Moxie.xap",
multi_selection: true,//false为单图上传,true为多图上传
filters : {
max_file_size : '100mb',//限制文件上传大小
mime_types: [
{title : "Image files", extensions : "jpg,gif,png"},//限制文件上传格式
]
},
init: {
//init事件发生后触发
PostInit: function() {
//document.getElementById('filelist').innerHTML = '';
document.getElementById('uploadfiles').onclick = function() {
uploader.start();
return false;
};
},
FilesAdded: function(up, files) {//文件选择之后的触发的方法
var len = len = files.length;
for(var i = 0; i<len; i++){
var file_name = files[i].name; //文件名
var file_size = files[i].size;//文件大小
//构造html来更新UI
//var html = '<li id="file-' + files[i].id +'"><p class="file-name">' + file_name + '(' + plupload.formatSize(file_size) + ')' + '</p><p class="progress"></p></li>';
var html = '<li id="file-' + files[i].id +'"><span class="close"></span></li>';
$(html).appendTo('#file-list');
!function(i){
previewImage(files[i],function(imgsrc){
$('#file-'+files[i].id).append('<a><img src="'+ imgsrc +'" /><span class="progress">12</span></a>');
})
}(i);
$("#uploadfiles").trigger('click');
}
/*plupload.each(files, function(file) {
document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';
});*/
}, UploadProgress: function(up, file) {//上传过程中调用的方法
//document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
$('#file-'+file.id +" .progress").html(file.percent + "%");
},
FileUploaded : function (up,file,res) {//文件上传完成后
console.log(res.response);
var data = JSON.parse(res.response).data;
$('#file-'+file.id).children('.close').attr('img_id',data.img_id);
var img = $("#images_upload");
var str = img.val();
if(str == ''){
str = data.img_id;
}else{
str += ','+data.img_id;
}
img.val(str);
},
Error: function(up, err) {
//document.getElementById('console').appendChild(document.createTextNode("\nError #" + err.code + ": " + err.message));
}
}
}); //plupload中为我们提供了mOxie对象
//有关mOxie的介绍和说明请看:https://github.com/moxiecode/moxie/wiki/API
//file为plupload事件监听函数参数中的file对象,callback为预览图片准备完成的回调函数
function previewImage(file,callback){
if(!file || !/image\//.test(file.type)) return; //确保文件是图片
if(file.type=='image/gif'){ //gif使用FileReader进行预览,因为mOxie.Image只支持jpg和png
var gif = new moxie.file.FileReader();
gif.onload = function(){
callback(gif.result);
gif.destroy();
gif = null;
};
gif.readAsDataURL(file.getSource());
}else{
var image = new moxie.image.Image();
image.onload = function() {
image.downsize( 150, 150 );//先压缩一下要预览的图片,宽300,高300
var imgsrc = image.type=='image/jpeg' ? image.getAsDataURL('image/jpeg',80) : image.getAsDataURL(); //得到图片src,实质为一个base64编码的数据
callback && callback(imgsrc); //callback传入的参数为预览图片的url
image.destroy();
image = null;
};
image.load( file.getSource() );
}
} uploader.init(); //移除图片
$("#file-list").on('click',".close",function(){
var img_id = $(this).attr("img_id");
var img = $("#images_upload");
var items=img.val().split(",");
var index = items.indexOf(img_id);
items.splice(index,1);//删除元素
img.val(items.join(','));
$(this).parent().remove();
});
</script>
</body>
</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. 基于Flume的美团日志收集系统 架构和设计 改进和优化

    3种解决办法 https://tech.meituan.com/mt-log-system-arch.html 基于Flume的美团日志收集系统(一)架构和设计 - https://tech.meit ...

  2. 观察OnPaint与OnIdle与OnSize事件

    import wx class SketchWindow(wx.Window): def __init__(self, parent, ID): wx.Window.__init__(self, pa ...

  3. 应用索引技术优化SQL 语句(转)

    原文出处 一.前言 很多数据库系统性能不理想是因为系统没有经过整体优化,存在大量性能低下的SQL 语句.这类SQL语句性能不好的首要原因是缺乏高效的索引.没有索引除了导致语句本身运行速度慢外,更是导致 ...

  4. [2017-12-20]ElasticSearch 小记

    介绍 ElasticSearch是一款搜索引擎中间件,因其强大的全文索引.查询统计能力和非常方便的全套基于Restful的接口,以及在自动分片.无停机升级扩容.故障转移等运维方面的高效性,逐渐成为中小 ...

  5. 2016WWDC详解

    今年苹果WWDC 2016上把所有系统都更新了个遍,watchOS.tvOS.macOS 和 iOS 都或多或少带来了新功能. 本文的主角是更新最多的 iOS 10,第一时间在一部 iPhone 6s ...

  6. Swift 烧脑体操(四) - map 和 flatMap

    前言 Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融入了大量新特性.这也使得我们学习掌握这门语言变得相对来说更加困 ...

  7. quick check

  8. callback机制之内核通知链表【转】

    本文转载自:http://bbs.chinaunix.net/thread-2011776-1-1.html 1.通知链表简介    大多数内核子系统都是相互独立的,因此某个子系统可能对其它子系统产生 ...

  9. python类初探

    class human: is_alive=True is_man=True def __init__(self,age): print('this is __init__() method, whi ...

  10. RQNOJ 514 字串距离:dp & 字符串

    题目链接:https://www.rqnoj.cn/problem/514 题意: 设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为”abcbcd”,则字 ...