超好用的原生 JS + Canvas 進行圖片壓縮
阿新 • • 發佈:2021-01-04
技術標籤:JavaScript
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<input type="file" id="upload">
<p id="p"></p>
<script>
const ACCEPT = ['image/jpg', 'image/png', 'image/jpeg', 'image/webp']; // 限定圖片檔案型別
const MAXSIZE = 1024 * 1024 * 3; // 限定圖片最大容量
const MAXSIZE_STR = '3MB';
function convertImageToBase64(file, cb) {
let reader = new FileReader();
reader.addEventListener('load', function (e) {
const base64Image = e.target.result; // 獲取檔案內容,等同於 reader.result
cb(base64Image);
reader = null;
});
reader.readAsDataURL(file); // 讀取 file 物件中的內容
}
function compress(base64Image, cb) {
let maxW = 1024;
let maxH = 1024;
const image = new Image();
image.addEventListener('load', function () {
let ratio; // 壓縮比
let needCompress = false; // 是否需要壓縮
if (maxW < image.naturalWidth) {
needCompress = true;
ratio = image.naturalWidth / maxW;
maxH = image.naturalHeight / ratio;
}
if (maxH < image.naturalHeight) {
needCompress = true;
ratio = image.naturalHeight / maxH;
maxW = image.naturalWidth / ratio;
}
if (!needCompress) {
maxW = image.naturalWidth;
maxH = image.naturalHeight;
}
const canvas = document.createElement('canvas');
canvas.setAttribute('id', '__compress__');
canvas.width = maxW;
canvas.height = maxH;
canvas.style.visibility = 'hidden';
document.body.append(canvas);
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, maxW, maxH);
ctx.drawImage(image, 0, 0, maxW, maxH); // 渲染圖片
const compressImage = canvas.toDataURL('image/jpeg', 0.9); // 壓縮圖片
cb(compressImage);
const _image = new Image();
_image.src = compressImage;
document.body.appendChild(_image);
canvas.remove(); // 移除 canvas
document.getElementById('p').innerHTML = `壓縮比 ${image.src.length / _image.src.length}`
});
image.src = base64Image; // 將圖片設定到 image 的 src 屬性中
document.body.appendChild(image);
}
function uploadImage(compressImage) {
console.log('upload image to server...', compressImage);
}
const upload = document.getElementById('upload');
upload.addEventListener('change', function (e) {
const file = e.target.files[0];
console.log(file);
if (!file) {
return;
}
const { type: fileType, size: fileSize } = file;
// 圖片型別檢查
if (!ACCEPT.includes(fileType)) {
alert('不支援上傳該格式檔案!');
upload.value = '';
return;
}
// 圖片大小檢查
if (fileSize > MAXSIZE) {
alert('檔案超出' + MAXSIZE_STR + '!');
upload.value = '';
return;
}
// 壓縮檔案
convertImageToBase64(file, (base64Image) => compress(base64Image, uploadImage));
});
</script>
</body>
</html>