标签:计算 min load tco compress 超过 nbsp tee char
import Exif from ‘exif-js‘; /* eslint-disable func-names */ function ImageProcess(file, callback) { let Orientation; // 去获取拍照时的信息,解决拍出来的照片旋转问题 Exif.getData(file, function () { Orientation = Exif.getTag(this, ‘Orientation‘); }); // console.log("Orientation", Orientation); // 看支持不支持FileReader if (!file || !window.FileReader) return; if (/^image/.test(file.type)) { // 创建一个reader const reader = new window.FileReader(); // 将图片2将转成 base64 格式 reader.readAsDataURL(file); // 读取成功后的回调 reader.onloadend = function () { const img = new window.Image(); img.src = this.result; img.onload = function () { // 压缩图片 const data = ImageCompress(img, Orientation); // console.log(dataURItoBlob(data)); callback(data); }; }; } } function ImageCompress(img, Orientation) { const canvas = document.createElement(‘canvas‘); const ctx = canvas.getContext(‘2d‘); // 瓦片canvas const tCanvas = document.createElement(‘canvas‘); const tctx = tCanvas.getContext(‘2d‘); let { width, height } = img; // 如果图片大于四百万像素,计算压缩比并将大小压至400万以下 let ratio = (width * height) / 4000000; if (ratio > 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万则使用瓦片绘制 let count = (width * height) / 1000000; if (count > 1) { // 计算要分成多少块瓦片 count = ~~(Math.sqrt(count) + 1); // 计算每块瓦片的宽和高 const nw = ~~(width / count); const nh = ~~(height / count); tCanvas.width = nw; tCanvas.height = nh; for (let i = 0; i < count; i += 1) { for (let j = 0; j < count; j += 1) { 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); } // 修复ios上传图片的时候 被旋转的问题 if (Orientation && Orientation !== 1) { switch (Orientation) { case 6: // 需要顺时针(向左)90度旋转 rotateImg(img, ‘left‘, canvas); break; case 8: // 需要逆时针(向右)90度旋转 rotateImg(img, ‘right‘, canvas); break; case 3: // 需要180度旋转 转两次 rotateImg(img, ‘right‘, canvas); rotateImg(img, ‘right‘, canvas); break; default: break; } } // 进行最小压缩 const ndata = canvas.toDataURL(‘image/jpeg‘, 0.5); // 清除canvas画布的宽高 tCanvas.width = 0; tCanvas.height = 0; canvas.width = 0; canvas.height = 0; // 打印压缩前后的大小,以及压缩比率 // const initSize = img.src.length; // console.log(‘压缩前:‘ + initSize); // console.log(‘压缩后:‘ + ndata.length); // console.log(‘压缩率:‘ + ~~(100 * (initSize - ndata.length) / initSize) + "%"); // console.log(ndata); return ndata; } function rotateImg(img, direction, cvs) { const canvas = cvs; // 最小与最大旋转方向,图片旋转4次后回到原方向 const minStep = 0; const maxStep = 3; if (img == null) return; // img的高度和宽度不能在img元素隐藏后获取,否则会出错 const { width, height } = img; let step = 2; if (step == null) { step = minStep; } if (direction === ‘right‘) { step += 1; // 旋转到原位置,即超过最大值 if (step > maxStep) step = minStep; } else { step -= 1; if (step < minStep) step = maxStep; } // 旋转角度以弧度值为参数 const degree = (step * 90 * Math.PI) / 180; const ctx = canvas.getContext(‘2d‘); switch (step) { case 0: canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0); break; case 1: canvas.width = height; canvas.height = width; ctx.rotate(degree); ctx.drawImage(img, 0, -height); break; case 2: canvas.width = width; canvas.height = height; ctx.rotate(degree); ctx.drawImage(img, -width, -height); break; case 3: canvas.width = height; canvas.height = width; ctx.rotate(degree); ctx.drawImage(img, -width, 0); break; default: break; } } function dataURItoBlob(dataURI) { const byteString = window.atob(dataURI.split(‘,‘)[1]); const mimeString = dataURI.split(‘,‘)[0].split(‘:‘)[1].split(‘;‘)[0]; // const ab = new ArrayBuffer(byteString.length); const ia = new Uint8Array(byteString.length); for (let i = 0; i < byteString.length; i += 1) { ia[i] = byteString.charCodeAt(i); } return new window.Blob([ia], { type: mimeString }); } export default ImageProcess;
标签:计算 min load tco compress 超过 nbsp tee char
原文地址:https://www.cnblogs.com/shangyueyue/p/10094812.html