本文实例为大家分享了Vue2.0实现调用摄像头进行拍照功能的具体代码,以及图片上传功能引用exif.js,供大家参考,具体内容如下
所需要的插件:https://download.csdn.net/download/qq_42396791/10728846
插件:
1.jquery.min.js
2.exif.js
效果目标:实现等比例压缩上传
上代码
HTML
点击上传封面
JS
//model
var data = {
keyurl:'',
key:'',
qiniutoken:'',
//修改详情
accept: ['image/gif', 'image/jpeg', 'image/png', 'image/bmp'],
width:'',
height:''
}
//ViewModel
var app = new Vue({
el: "#app",
data: data,
created: function() {
//获取数据
//获取七牛token
this.qiniutk();
},
methods: {
//获取qiniu
qiniutk:function(){
this.$http.get('qiniutokenUrl').then(function(r){
var token = r.data.data;
this.qiniutoken = token;
});
},
//用户上传
fileChange:function(el){
let file = el.target.files[0];
let type = file.type;//文件类型
let size = file.size;//文件大小
if (this.accept.indexOf(type)==-1) {
layer.msg("请选择我的支持的图片格式");
return false;
};
if (size>3145728){
layer.msg("请选择3M以内的图片");
return false;
};
if (!file.size) return;//判断是否有文件数量
if (!file) return; // 未上传
var orientation; // 图片上传的角度,解决
/**
* 利用exif.js解决ios手机上传竖拍照片旋转90度问题
* 详见 http://code.ciaoca.com/javascript/exif-js/
*/
EXIF.getData(file, function () { // 获取照片方向角属性,用户旋转控制
orientation = EXIF.getTag(this, 'Orientation');
});
var reader = new FileReader(); // 读取文件
var self = this;
reader.onload = function () {
self.getImgData(this.result, orientation, function (result) {
var img = new Image();
img.src = result;
// 如果图片大小小于200kb,则直接上传
if (result.length <= 200) {
self.fileList(file); //调用上传接口函数:无需压缩
img = null;
return;
};
// 图片加载完毕之后进行压缩,然后上传
if (img.complete) {
callback();
} else {
img.onload = callback;
};
function callback () {
var data = self.compress(img);//这个就是base64的数据了
//self.keyurl = data;//渲染原始图像
//console.log(img.width +'----'+img.height);//这里就是上传图片的宽和高了
var file = self.dataURLtoFile(data,'1.png');//将base64转换为文件
self.fileList(file);//调用上传接口函数:压缩版本
img = null;
}
});
};
reader.readAsDataURL(file);
//this.fileList(file);//获取files文件组传入处理:未压缩版本
},
dataURLtoFile:function(dataurl, filename){//将base64转换为文件
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/),
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type:mime});
},
compress:function(img) {
// 用于压缩图片的canvas
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// 瓦片canvas
var tCanvas = document.createElement('canvas');
var tctx = tCanvas.getContext('2d');
let initSize = img.src.length
// 获取父元素宽高
let parentWh = $('.creater_class .files');
let wid = parentWh.width();
let hei = parentWh.height();
//console.log("父亲:"+wid+'...'+hei)
//console.log("原始图片:"+img.width+'...'+img.height)
// 等比压缩图片
this.AutoSize(img, wid, hei);
var width = this.width;
var height = this.height;
//console.log("变小图片:"+width+'...'+height)
// 如果图片大于四百万像素,计算压缩比并将大小压至400万以下
var ratio;
if ((ratio = width * height / 4000000) > 1) {
ratio = Math.sqrt(ratio);
width /= ratio;
height /= ratio;
} else {
ratio = 1;
}
canvas.width = width;
canvas.height = height;
// 铺底色
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 如果图片像素大于100万则使用瓦片绘制
var count;
if ((count = width * height / 1000000) > 1) {
count = ~~(Math.sqrt(count) + 1); // 计算要分成多少块瓦片
// 计算每块瓦片的宽和高
var nw = ~~(width / count);
var nh = ~~(height / count);
tCanvas.width = nw;
tCanvas.height = nh;
for (let i = 0; i < count; i++) {
for (let j = 0; j < count; j++) {
tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
}
}
} else {
ctx.drawImage(img, 0, 0, width, height);
}
// 进行最小压缩0.1
var ndata = canvas.toDataURL('image/jpeg', 0.5);
// console.log('压缩前:' + initSize)
// console.log('压缩后:' + ndata.length)
// console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%")
tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
return ndata;
},
AutoSize:function(image, maxWidth, maxHeight) {// 等比压缩图片
// 当图片比图片框小时不做任何改变
if (image.width < maxWidth && image.height < maxHeight) {
//原图片宽高比例 大于 图片框宽高比例
this.width = image.width;
this.height = image.height;
} else {
//原图片宽高比例 大于 图片框宽高比例,则以框的宽为标准缩放,反之以框的高为标准缩放
if (maxWidth / maxHeight <= image.width / image.height) {
this.width = maxWidth; //以框的宽度为标准
this.height = maxWidth * (image.height / image.width);
} else {
this.width = maxHeight * (image.width / image.height);
this.height = maxHeight; //以框的高度为标准
}
}
},
getImgData:function(img, dir, next) {
var image = new Image();
image.onload = function () {
var degree = 0;
var drawWidth;
var drawHeight;
var width;
var height;
drawWidth = this.naturalWidth;
drawHeight = this.naturalHeight; // 以下改变一下图片大小
var maxSide = Math.max(drawWidth, drawHeight);
if (maxSide > 1024) {
var minSide = Math.min(drawWidth, drawHeight);
minSide = minSide / maxSide * 1024;
maxSide = 1024;
if (drawWidth > drawHeight) {
drawWidth = maxSide;
drawHeight = minSide;
} else {
drawWidth = minSide;
drawHeight = maxSide;
}
}
var canvas = document.createElement('canvas');
canvas.width = width = drawWidth;
canvas.height = height = drawHeight;
var context = canvas.getContext('2d'); // 判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式
switch (dir) {
// iphone横屏拍摄,此时home键在左侧
case 3:
degree = 180
drawWidth = -width
drawHeight = -height
break
// iphone竖屏拍摄,此时home键在下方(正常拿手机的方向)
case 6:
canvas.width = height
canvas.height = width
degree = 90
drawWidth = width
drawHeight = -height
break
// iphone竖屏拍摄,此时home键在上方
case 8:
canvas.width = height
canvas.height = width
degree = 270
drawWidth = -width
drawHeight = height
break
}
// 使用canvas旋转校正
context.rotate(degree * Math.PI / 180)
context.drawImage(this, 0, 0, drawWidth, drawHeight)
// 返回校正图片
next(canvas.toDataURL('image/jpeg', 0.8))
}
image.src = img
},
fileList:function(files){
// 调用七牛的单图片上传接口,获取返回的key
this.imageUpload(files);
},
imageUpload:function(fileDom){
var imageData = new FormData();
imageData.append('file',fileDom);
imageData.append('token',this.qiniutoken);
this.$http.post('qiniuUrl',imageData).then((result)=>{
//this.keyurl = 'http://paz4semup.bkt.clouddn.com/' + result.data.key;//渲染上传的图像
this.key = result.data.key;
});
}
}
});
完整代码:https://download.csdn.net/download/qq_42396791/10729262