图片压缩的几种方式

📅 2026/7/16 9:28:11 👁️ 阅读次数 📝 编程学习
图片压缩的几种方式
// 图片压缩统一转webp格式处理 export function compressImageToWebp( file: File, options?: { maxWidth?: number; quality?: number }, callback: (file: File) => void ) { const { maxWidth = 800, quality = 0.8 } = options || {}; const reader = new FileReader(); reader.onload = e => { const img = new Image(); img.onload = () => { let { width, height } = img; if (width > maxWidth) { height = (maxWidth / width) * height; width = maxWidth; } const canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; const ctx = canvas.getContext('2d'); ctx?.drawImage(img, 0, 0, width, height); canvas.toBlob( blob => { if (!blob) return; const compressedFile = new File( [blob], file.name.replace(/\.(png|jpe?g)$/i, '.webp'), { type: 'image/webp', lastModified: Date.now(), } ); callback(compressedFile); }, 'image/webp', quality ); }; img.src = e.target!.result as string; }; reader.readAsDataURL(file); }
// File 类型压缩 export function compressFile(file: File, callback: Function) { const reader = new FileReader(); reader.onload = function (event: any) { const img: any = new Image(); img.onload = function () { const canvas = document.createElement("canvas"); const MAX_WIDTH = 800; const MAX_HEIGHT = 600; let width = img.width; let height = img.height; if (width > height) { if (width > MAX_WIDTH) { height *= MAX_WIDTH / width; width = MAX_WIDTH; } } else { if (height > MAX_HEIGHT) { width *= MAX_HEIGHT / height; height = MAX_HEIGHT; } } canvas.width = width; canvas.height = height; const ctx: any = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, width, height); canvas.toBlob( function (blob: any) { // 将 Blob 对象转换为 File 对象,保持原有的文件名和类型 const compressedFile = new File([blob], file.name, { type: file.type, }); callback(compressedFile); }, file.type, 0.92, ); // 质量参数,范围是 0 到 1,0.92 表示92%的质量 }; img.src = event.target.result; // 设置 img 的 src 为 FileReader 的结果,即图片的 URL }; reader.readAsDataURL(file); // 读取文件内容为 DataURL }
// base64 类型压缩 export function imageCompress(base64: string) { let Img = new Image(), dataURL = ""; Img.src = base64; let pic = new Promise(function (resolve) { Img.onload = function () { //要先确保图片完整获取到,这是个异步事件 let canvas: any = document.createElement("canvas"), //创建canvas元素 width = Img.width, //确保canvas的尺寸和图片一样 height = Img.height; // 默认将长宽设置为图片的原始长宽,这样在长宽不超过最大长度时就不需要再处理 let ratio = width / height, maxLength = 1000, newHeight = height, newWidth = width; // 在长宽超过最大长度时,按图片长宽比例等比缩小 if (width > maxLength || height > maxLength) { if (width > height) { newWidth = maxLength; newHeight = maxLength / ratio; } else { newWidth = maxLength * ratio; newHeight = maxLength; } } canvas.width = newWidth; canvas.height = newHeight; canvas.getContext("2d").drawImage(Img, 0, 0, newWidth, newHeight); //将图片绘制到canvas中 dataURL = canvas.toDataURL("image/jpeg", 0.5); //转换图片为dataURL resolve(dataURL); }; }); return pic; }
// 图片统一转webp格式来压缩 export function compressImageToWebp( file: File, callback: (file: File) => void, options?: { maxWidth?: number; maxHeight?: number; quality?: number }, ) { const { maxWidth = 2000, maxHeight = 3000, quality = 0.98 } = options || {}; const reader = new FileReader(); reader.onload = (e) => { const img = new Image(); img.onload = () => { let { width, height } = img; if (width > height) { if (width > maxWidth) { height *= maxWidth / width; width = maxWidth; } } else { if (height > maxHeight) { width *= maxHeight / height; height = maxHeight; } } const canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; const ctx = canvas.getContext("2d"); ctx?.drawImage(img, 0, 0, width, height); canvas.toBlob( (blob) => { if (!blob) return; console.log("blob++++", blob); const compressedFile = new File( [blob], file.name.replace(/\.(png|jpe?g)$/i, ".webp"), { type: "image/webp", lastModified: Date.now(), }, ); callback(compressedFile); }, "image/webp", quality, ); }; img.src = e.target!.result as string; }; reader.readAsDataURL(file); }
使用成熟库 import imageCompression from "browser-image-compression"; export async function compressImage(file: any) { const options = { maxSizeMB: 5, // 目标最大体积 (MB) // maxWidthOrHeight: 1920, // 最大宽高限制 useWebWorker: true, // 启用多线程防阻塞 // fileType: "image/png", //限制上传的图片格式,这里不做限制 mimeType: "image/png", // 指定压缩后图片的格式 }; try { const blobFile = await imageCompression(file, options); const compressedFile = new File([blobFile], file.name, { type: file.type, }); return compressedFile; } catch (error) { console.error("压缩失败:", error); } }

接收处理的地方:

const compressedFiles = acceptedFiles.map((i: any, j: number) => { if (i.size > 5 * 1024 * 1024) { compressImage(i, (compressedFile: any) => { i = compressedFile; return i; }); }else{ return i; } });

let compressedFiles:any = [] for(let i = 0; i < acceptedFiles.length; i++){ if (acceptedFiles[i].size > 5 * 1024 * 1024) { // 大于5M,需要压缩 setSubmitMaterialsLoading(true); handleMyAdmToast(true, '图片压缩中'); const compressRes:any = await compressImage(acceptedFiles[i]); compressedFiles.push(compressRes) setSubmitMaterialsLoading(false); handleMyAdmToast(false); }else{ compressedFiles.push(acceptedFiles[i]) } }