分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 技术分享

图片上传压缩校正

发布时间:2023-09-06 02:25责任编辑:彭小芳关键词:暂无标签
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;
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;

图片上传压缩校正

原文地址:https://www.cnblogs.com/shangyueyue/p/10094812.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved