话不多说直接上代码…
方式一:
template:
<input
type="file"
:value="imgValue"
class="uploadInput"
accept="image/*"
@change="uploadImg($event)"
/>
script:
uploadImg(event) {
let _this = this;
let files = event.target.files[0];
let imgDataUrl = this.getObjectURL(files);
var image = new Image();
image.src = imgDataUrl;
image.setAttribute("crossOrigin", "Anonymous");
image.onload = function() {
// 缩放图片需要的canvas(也可以在DOM中直接定义canvas标签,这样就能把压缩完的图片不转base64也能直接显示出来)
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
// 图片原始尺寸
var originWidth = this.width;
var originHeight = this.height;
// 最大尺寸限制,可通过设置宽高来实现图片压缩程度
var maxWidth = 500,
maxHeight = 500;
// 目标尺寸
var targetWidth = originWidth,
targetHeight = originHeight;
// 图片尺寸超过300x300的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth;
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
} else {
targetHeight = maxHeight;
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
}
}
// canvas对图片进行缩放
canvas.width = targetWidth;
canvas.height = targetHeight;
// 清除画布
context.clearRect(0, 0, targetWidth, targetHeight);
// 图片压缩
context.drawImage(image, 0, 0, targetWidth, targetHeight);
/*第一个参数是创建的img对象;第二三个参数是左上角座标,后面两个是画布区域宽高*/
//压缩后的图片转base64 url
/*canvas.toDataURL(mimeType, qualityArgument),mimeType 默认值是'image/png';
* qualityArgument表示导出的图片质量,只有导出为jpeg和webp格式的时候此参数才有效,默认值是0.92*/
var base64 = canvas.toDataURL("image/jpeg", 0.92); //base64 格式
//传给后台 base64
};
},
getObjectURL(file) {
let url = null;
if (window.createObjectURL != undefined) {
// basic
url = window.createObjectURL(file);
} else if (window.webkitURL != undefined) {
// webkit or chrome
url = window.webkitURL.createObjectURL(file);
} else if (window.URL != undefined) {
// mozilla(firefox)
url = window.URL.createObjectURL(file);
}
return url;
},
方式二:
图片处理部分分为
1.读取上传文件
2.转换 base64 编码
3.使用 canvas 压缩图片
4.上传图片
script
uploadImg(e) {
this.show1 = true
this.text1 = '正在解析图片'
let files = e.target.files || e.dataTransfer.files
let id = e.target.id
if (!files.length) return
this.picavalue = files[0]
console.log(this.picavalue.size / 1024)
if (this.picavalue.size / 1024 > 10240) {
this.$vux.alert.show({
title: '温馨提示',
content: '图片过大,请重新上传'
})
} else {
this.text1 = '正在获取图片'
this.imgPreview(this.picavalue, id)
}
},
//获取图片
imgPreview(file, id) {
this.text1 = '正在压缩图片'
let self = this
//判断支不支持FileReader
if (!file || !window.FileReader) return false
if (/^image/.test(file.type)) {
//创建一个reader
let reader = new FileReader()
//将图片转成base64格式
reader.readAsDataURL(file)
//读取成功后的回调
reader.onloadend = function() {
let result = this.result
let img = new Image()
img.src = result
console.log('********未压缩前的图片大小********')
console.log(result.length / 1024)
img.onload = function() {
let data = self.compress(img, 0.3)
self.uploadImg(data, id)
}
}
}
},
// 压缩图片
compress(img, size) {
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
let initSize = img.src.length
let width = img.width
let height = img.height
canvas.width = width
canvas.height = height
// 铺底色
ctx.fillStyle = '#fff'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(img, 0, 0, width, height)
//进行最小压缩
let ndata = canvas.toDataURL('image/jpeg', size)
console.log('*******压缩后的图片大小*******')
// console.log(ndata)
console.log(ndata.length / 1024)
return ndata
},
uploadImg(base64, id) {
console.log('得到压缩后的base64传入后台')
})
},
另外附一种基于jq
<!DOCTYPE html">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title> upload image to db demo </title>
<script src="jquery-2.1.1.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
img {
width: 100%;
}
</style>
<script type="text/javascript">
$(function() {
var maxSize = 200 * 1024; //图片小于200K不用压缩
$('#photo').change(function() {
var files = this.files[0];
//console.log(files)
//获取图片大小
var size = files.size / 1024 > 1024 ? Math.round(parseFloat(files.size / 1024 / 1024) * 100) / 100 + "MB" : Math.round(parseFloat(files.size / 1024 * 100)) / 100 + "KB";
var reader = new FileReader();
reader.readAsDataURL(files); //以数据URL形式读取img
reader.onload = function() {
var img = new Image();
img.src = this.result;
var base64Data = this.result; //获取图片的64位转码
$('#rs img').attr('src', base64Data); //预览
if(base64Data.length <= maxSize) {
postBlob(base64Data); //图片小于200K,直接上传
img = null;
} else {
//console.log('图片大于200K');
//console.log(img.complete);
if(img.complete) {//这个判断很重要,不然会有bug
callback();
} else {
img.onload = callback;
}
}
function callback() {//该函数放在reader的onload方法内
var bigger64Data = compress(img);
postBlob(bigger64Data);
}
}
});
function compress(img) {//压缩图片的方法
//console.log(img)
var initSize = img.src.length;
//用于压缩图片的canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
//瓦片canvas
var tCanvas = document.createElement("canvas");
var tctx = tCanvas.getContext("2d");
var width = img.width;
var height = img.height;
//如果图片大于四百万像素,计算压缩比并将大小压至400万 大约等于4Mb以下
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 = "#fff";
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(var i = 0; i < count; i++) {
for(var 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);
} // 进行最小压缩
var ndata = canvas.toDataURL('image/jpeg', 0.1);
// 压缩比例1/10
console.log('压缩前:' + initSize);
console.log('压缩后:' + ndata.length);
console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");
tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
//console.log(ndata);
return ndata;
}
function dataURItoBlob(base64Data) { //64位数据转为 blob数据
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
});
}
function postBlob(base64data) { //提交blob数据
var blob = dataURItoBlob(base64data); //转成blod格式
var fd = new FormData();
fd.append("photo", blob); //fd为自定义
$.ajax({
type: 'POST',
url: 'up.php',
data: fd,
//如果传递的是FormData数据类型,那么下来的三个参数是必须的,否则会报错
cache: false, //默认是true,但是一般不做缓存
processData: false, //用于对data参数进行序列化处理,这里必须false;如果是true,就会将FormData转换为String类型
contentType: false, //一些文件上传http协议的关系,自行百度,如果上传的有文件,那么只能设置为false
}).success(function(res) {
//console.log(res);
alert('上传成功')
}).error(function(err) {
console.error(err);
});
}
});
</script>
</head>
<body>
<input type="file" id="photo" name="photo" accept="image/*" multiple>
<div id="rs">
<img src="" />
</div>
</body>
</html>
本人项目中用的第一种方式,效果很棒,其他两种大家可以参考呢!
好了就到这里了,欢迎评论点赞留言,一起加油!