最近遇到一个功能需要前端上传图片到七牛云,并且压缩上传图片。
上传的动作主要是通过input[type=file]来完成,但是由于input[type=file]的样式并不美观,所以需要想办法隐藏input[type=file],通过其他可以自定义样式的按钮去触发input[type=file]的上传事件。
我这里主要是通过“x-file”这个类名隐藏input[type=file]标签的。
压缩图片主要是通过canvas实现。核心代码截图如下:
实现图片压缩并上传至七牛云的完整代码:
html代码
<div id="box">
<div class="form-group">
<label class="col-sm-2 control-label"><strong class="red">*strong>上传头像label>
<div class="col-sm-9">
<button id="btnCardAdd" class="btn btn-primary" type="button" onclick="document.getElementById('cardFileupload').click();"><i class="fa fa-plus">i> 选择图片button>
<input type="file" id="cardFileupload" class="x-file" onchange="repairman.loadLocalImage(this,'cardImage',0);" accept="image/*" />
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">label>
<div class="col-sm-9" id="uploadImgBox">
<img class="cardImage" style="margin-top: 10px; width: 100px; height: 100px; max-width: 400px; border: 10px solid #EEEEEE;" src='../../images/award_default.jpg' />
div>
div>
div>
css代码
.x-file{
position: absolute;
top: 0;
left: 0;
width: 0px;
height: 0px;
filter: alpha(opacity=0);
-moz-opacity: 0;
-khtml-opacity: 0;
opacity: 100;
background: #000000;
border: none;
cursor: pointer;
}
js代码
//图片上传
loadLocalImage: function(fileObject, imageID, imageType) {
if (typeof FileReader == 'undefined') {
alert("当前浏览器不支持FileReader接口");
return;
}
var file = fileObject.files[0];
let reader = new FileReader();//新建一个FileReader对象
reader.readAsDataURL(file);//将读取的文件转换成base64格式
reader.onload = function (e) {
// 压缩图片
var image = new Image() //新建一个img标签(不嵌入DOM节点,仅做canvas操作)
image.src = e.target.result //让该标签加载base64格式的原图
image.onload = function () { //图片加载完毕后再通过canvas压缩图片,否则图片还没加载完就压缩,结果图片是全黑的
let canvas = document.createElement('canvas'), //创建一个canvas元素
context = canvas.getContext('2d'), //context相当于画笔,里面有各种可以进行绘图的API
imageWidth = image.width / 2, //压缩后图片的宽度,这里设置为缩小一半
imageHeight = image.height / 2, //压缩后图片的高度,这里设置为缩小一半
data = '' //存储压缩后的图片
canvas.width = imageWidth //设置绘图的宽度
canvas.height = imageHeight //设置绘图的高度
//使用drawImage重新设置img标签中的图片大小,实现压缩。drawImage方法的参数可以自行查阅W3C
context.drawImage(image, 0, 0, imageWidth, imageHeight)
//使用toDataURL将canvas上的图片转换为base64格式
data = canvas.toDataURL('image/jpeg');
var blobURL = repairman.dataURItoBlob(data);
// 图片上传至七牛云
repairman.qiniuUpload(
blobURL,
// file.name,
'bjx_' + new Date().getTime() + (parseInt(Math.random() * 100 + 1)),
$('#uploadImgBox')
);
}
}
},
// base64转blob
dataURItoBlob: function(base64Data) {
var byteString;
if(base64Data.split(',')[0].indexOf('base64') >= 0)
byteString = atob(base64Data.split(',')[1]);
else
byteString = unescape(base64Data.split(',')[1]);
var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0];
var ia = new Uint8Array(byteString.length);
for(var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {
type: mimeString
});
},
/**七牛云上传图片
* cardImageUrl-----需要上传图片的bolb地址
* token-----token
* fileName-----上传图片的原文件名
* nodeObj------显示图片的盒子
* */
qiniuUpload: function(cardImageUrl, fileName, nodeObj) {
$.ajax({
url: win.utils.services.getQiniuToken,
type: 'get',
dataType: 'json',
success: function (res) {
var qiniuToken = res.token;
var observable = qiniu.upload(
cardImageUrl,
fileName,
qiniuToken,
{
fname: fileName,
params: {}, //用来放置自定义变量
mimeType: null
}, {
useCdnDomain: true,
region: null
}
);
observable.subscribe({
complete(res) {
var qiniuImgUrl = '七牛云地址'+res.key;
$('#uploadImgBox img').attr('src', qiniuImgUrl);
utils.showMessage('图片上传成功!');
$('input[type="file"]').val(""); //上传成功后将input[type=file]的值置为空,这样在删除当前图片以后还可以重新上传同一张图片
}
});
}
});
},