話不多說直接上代碼…
方式一:
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>
本人項目中用的第一種方式,效果很棒,其他兩種大家可以參考呢!
好了就到這裏了,歡迎評論點贊留言,一起加油!