<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input id="upload" type="file"/>
<script>
const FILETYPES = ["image/png", "image/jpg", "image/jpeg"]; // 受支持的文件類型
const MAX_FILESIZE = 1024 * 1024 * 3; // 1024 * 1024 為1M
const MAX_FILESIZESTRING = "3M"; // 文件大小字符
const COMPRESSRATIO = .5; // 壓縮比例 0 - 1
const upload = document.querySelector("#upload");
const imageToBase64 = (file, callback) => {
const reader = new FileReader();
reader.readAsDataURL(file); // 文件轉base64
reader.addEventListener("load", (e) => {
callback && callback(e.target.result);
});
};
const compress = (originalImage, compressRatio = 1, callback) => {
const image = new Image();
image.src = originalImage;
// document.body.appendChild(image); // 原圖預覽
/* 監聽圖片的load事件 */
image.addEventListener("load", function () {
let [sizeRatio, maxWidth, maxHeight] = [0, 1024, 1024]; // 圖片壓縮寬高比例和最大寬高
let [imageWidth, imageHeight] = [this.naturalWidth, this.naturalHeight]; // 圖片實際寬高
let compressFlag = false; // 圖片是否需要壓縮
// 如果圖片寬度大於最大寬度就等比壓縮圖片的高度
if (imageWidth > maxWidth) {
compressFlag = true;
sizeRatio = imageWidth / maxWidth;
maxHeight = imageHeight / sizeRatio;
}
// 如果圖片高度大於最大高度就等比壓縮圖片的寬度
if (imageHeight > maxHeight) {
compressFlag = true;
sizeRatio = imageHeight / maxHeight;
maxWidth = imageWidth / sizeRatio;
}
// 如果不需要壓縮
if (!compressFlag) {
maxWidth = imageWidth;
maxHeight = imageHeight;
}
// 使用canvas壓縮圖片
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.setAttribute("id", "canvas");
canvas.width = maxWidth;
canvas.height = maxHeight;
// document.body.appendChild(canvas); // canvas預覽
ctx.clearRect(0, 0, maxWidth, maxHeight); // 清除畫布內所有像素
ctx.drawImage(image, 0, 0, maxWidth, maxHeight); // canvas繪制當前圖片
const compressImage = canvas.toDataURL("image/jpeg", compressRatio); // 設置壓縮類型和壓縮比例獲取壓縮后的文件
callback && callback(compressImage);
});
}
upload.addEventListener("change", function (e) {
const [file] = e.target.files;
if (!file) this.value = ""; // file為空就阻止向下執行
const {type: fileType, size: fileSize} = file; // 獲取文件類型和大小
// 檢查是否支持的文件類型
if (!FILETYPES.includes(fileType)) {
this.value = "";
alert(`不支持${fileType}類型文件`);
return;
}
// 檢查文件大小
if (fileSize > MAX_FILESIZE) {
this.value = "";
alert(`文件不能超過${MAX_FILESIZESTRING}`);
return;
}
imageToBase64(file, (originalImage) => {
compress(originalImage, COMPRESSRATIO, (compressImage) => {
const _img = new Image();
_img.src = compressImage;
const download = document.createElement("a");
download.href = compressImage;
download.innerText = "點擊保存";
download.setAttribute("download", "demo.jpg");
document.body.appendChild(download);
document.body.appendChild(_img); // 壓縮后的圖片預覽
});
});
})
</script>
</body>
</html>