JavaScript 前端图片压缩方案,支持方向识别和修正
可以用于浏览器的图片压缩方案
js
import Exif from "exif-js"; // 图片信息识别库,用于识别方向信息
const compress = (file, result) => {
// 压缩图片
const orientation = Exif.getTag(file, "Orientation");
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = (ev) => {
const imgFile = ev.target.result;
const img = new Image();
img.src = imgFile;
img.onload = () => {
const compressBase64 = doCompress(img, orientation);
result(compressBase64); //回调结果
};
};
};
const doCompress = (img, orientation) => {
let imgWidth = img.width;
let imgHeight = img.height;
if (imgWidth > 1334) {
imgHeight = imgHeight * (1334 / imgWidth);
imgWidth = 1334;
} else if (imgHeight > 1334) {
imgWidth = imgWidth * (1334 / imgHeight);
imgHeight = 1334;
}
let canvas = document.createElement("canvas");
canvas.width = imgWidth;
canvas.height = imgHeight;
let ctx = canvas.getContext("2d");
ctx.fillStyle = "#fff"; // 铺底色
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘图之前 纠正图片的方向
if (orientation && orientation != 1) {
switch (orientation) {
case 6:
canvas.width = imgHeight;
canvas.height = imgWidth;
ctx.rotate(Math.PI / 2);
ctx.drawImage(img, 0, -imgHeight, imgWidth, imgHeight);
break;
case 3:
ctx.rotate(Math.PI);
ctx.drawImage(img, -imgWidth, -imgHeight, imgWidth, imgHeight);
break;
case 8:
canvas.width = imgHeight;
canvas.height = imgWidth;
ctx.rotate((3 * Math.PI) / 2);
ctx.drawImage(img, -imgWidth, 0, imgWidth, imgHeight);
break;
}
} else {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
//进行最小压缩
const u = navigator.userAgent;
const isAndroid = u.indexOf("Android") > -1 || u.indexOf("Adr") > -1; //android终端
// const isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
let pressedBase64 = canvas.toDataURL("image/jpeg", isAndroid ? 0.2 : 0.1);
return pressedBase64;
};
const baseUrltoBlob = (base64Data) => {
// base64转成bolb对象
let byteString;
if (base64Data.split(",")[0].indexOf("base64") >= 0) byteString = atob(base64Data.split(",")[1]);
else byteString = unescape(base64Data.split(",")[1]);
let mimeString = base64Data.split(",")[0].split(":")[1].split(";")[0];
let ia = new Uint8Array(byteString.length);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {
type: mimeString,
});
};
export { compress, baseUrltoBlob };