javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > 前端图片压缩方案

前端图片压缩方案学习详细代码示例

作者:香香的锤子

图片上传是前端中常见的的业务场景,无论是前台还是后台,适当的对图片进行压缩处理,可以显著的提升用户体验,这篇文章主要介绍了前端图片压缩方案学习的相关资料,需要的朋友可以参考下

一、前言

在Web开发中,图片资源通常占据页面加载流量的较大比例,直接影响用户体验和性能指标。未经压缩的图片会导致页面加载缓慢、带宽消耗增加,尤其在移动端或弱网环境下更为明显。合理的图片压缩能在视觉质量可接受的范围内显著减小文件体积,提升页面加载速度,降低服务器压力,并优化SEO评分。因此,前端图片压缩是性能优化中不可或缺的一环。

二、主流开箱即用的前端图片压缩方案

1. TinyPNG/TinyJPG API

TinyPNG/TinyJPG 提供图片压缩服务,通过减少颜色数量优化PNG和JPEG文件,压缩率通常达50%-80%,其前端 API 允许开发者通过 HTTP 请求直接调用压缩功能。需注册获取 API Key(免费版每月 500 次压缩)。

获取 API Key

  1. 访问 TinyPNG 开发者页面
  2. 填写邮箱并提交,API Key 将通过邮件发送。

前端 API 调用方法

使用 fetchaxios 发送 POST 请求,需包含 Authorization 头部和图片二进制数据。

请求格式

示例代码(JavaScript)

使用 Fetch API

async function compressImage(file) {
  const apiKey = 'YOUR_API_KEY'; // 替换为实际 API Key
  const auth = btoa(`api:${apiKey}`);
  
  const response = await fetch('https://api.tinify.com/shrink', {
    method: 'POST',
    headers: {
      'Authorization': `Basic ${auth}`,
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: file,
  });

  if (!response.ok) throw new Error('压缩失败');
  const data = await response.json();
  console.log('压缩结果:', data.output.url); // 压缩后的图片 URL
}

// 示例:处理用户上传的文件
document.getElementById('fileInput').addEventListener('change', (e) => {
  compressImage(e.target.files[0]);
});

使用 Axios

import axios from 'axios';

async function compressImage(file) {
  const apiKey = 'YOUR_API_KEY';
  const auth = btoa(`api:${apiKey}`);

  try {
    const response = await axios.post('https://api.tinify.com/shrink', file, {
      headers: {
        'Authorization': `Basic ${auth}`,
        'Content-Type': 'application/x-www-form-urlencoded',
      },
    });
    console.log('压缩结果:', response.data.output.url);
  } catch (error) {
    console.error('压缩失败:', error);
  }
}

注意事项

  1. 跨域问题: 前端直接调用可能触发 CORS 限制,建议通过后端中转或配置代理。
  2. 免费限制: 免费版每月 500 次请求,超出需付费。
  3. 响应数据: 成功时返回 JSON,包含 output.url(压缩后图片地址)和大小信息。

错误处理

通过捕获异常并检查响应状态码可针对性处理。

2. Compressor.js

Compressor.js 是一个基于 JavaScript 的图像压缩库,通过调整图像质量、尺寸等参数实现前端图像压缩,支持输出 Blob、File 或 Base64 格式。

基本使用方法

安装 Compressor.js 可通过 npm 或直接引入 CDN:

npm install compressorjs
<script src="https://cdn.jsdelivr.net/npm/compressorjs@1.1.1/dist/compressor.min.js"></script>

核心 API

new Compressor(file, options) 是主要构造函数,参数说明:

示例代码

基础压缩示例,输出为 Blob:

const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', (e) => {
  const file = e.target.files[0];
  new Compressor(file, {
    quality: 0.6,
    success(result) {
      const formData = new FormData();
      formData.append('file', result, result.name);
      // 上传逻辑
    },
    error(err) {
      console.error(err.message);
    },
  });
});

常用配置选项

new Compressor(file, {
  quality: 0.8,
  width: 800,
  height: 600,
  mimeType: 'image/webp',
  convertSize: 1000000, // 1MB
});

进阶用法

输出 Base64 格式:

new Compressor(file, {
  quality: 0.7,
  success(result) {
    const reader = new FileReader();
    reader.readAsDataURL(result);
    reader.onload = () => {
      console.log(reader.result); // Base64 字符串
    };
  }
});

注意事项

3. ImageMagick(通过wasm移植)

ImageMagick 前端 API 使用方法

ImageMagick 通常作为后端工具使用,但可以通过前端 JavaScript 封装或 WASM 版本调用。以下是常见的前端集成方法:

使用 WASM 版本(MagickWASM)

MagickWASM 是 ImageMagick 的 WebAssembly 移植版本,支持浏览器环境运行。

安装依赖:

npm install @imagemagick/magick-wasm

基础示例(图像格式转换):

import { Magick, MagickFormat } from '@imagemagick/magick-wasm';

async function convertImage(inputBlob) {
  const inputBytes = new Uint8Array(await inputBlob.arrayBuffer());
  const outputBytes = await Magick.Image.fromBlob(inputBytes).then(img => {
    img.write(MagickFormat.Png, data => data);
    return data;
  });
  return new Blob([outputBytes], { type: 'image/png' });
}

使用 JavaScript 封装库

wasm-imagemagick 是另一个封装方案:

安装:

npm install wasm-imagemagick

调整图像大小示例:

import { callMagickCli } from 'wasm-imagemagick';

async function resizeImage(file) {
  const files = [{ name: file.name, content: file }];
  const command = ['convert', file.name, '-resize', '50%', 'output.jpg'];
  const { stdout, stderr, outputFiles } = await callMagickCli({ inputFiles: files, commands: [command] });
  return outputFiles[0];
}

浏览器直接加载 WASM

通过 CDN 直接加载:

<script src="https://cdn.jsdelivr.net/npm/@imagemagick/magick-wasm@latest/dist/magick-api.js"></script>
<script>
  MagickAPI.ready.then(() => {
    Magick.Image.read('input.jpg').then(image => {
      image.resize(800, 600);
      image.write('output.jpg', blob => {
        const url = URL.createObjectURL(blob);
        document.getElementById('result').src = url;
      });
    });
  });
</script>

注意事项

以上方法均需现代浏览器支持,适合需要客户端图像处理的场景,但性能不及原生后端实现。ImageMagick作为经典图像处理工具,可通过Emscripten编译为WebAssembly在前端使用。功能强大,支持格式转换、尺寸调整及高级压缩参数设置。

三、自定义图片压缩方案的设计实现

1. 核心流程设计

  1. 文件读取与解码:通过FileReader读取用户上传的图片文件,使用CanvasImage对象解码为像素数据。
  2. 质量调整与尺寸缩放:利用CanvasdrawImagetoDataURL方法,调整输出质量(如0.7表示70%质量)或按比例缩放尺寸。
  3. 格式转换:优先转换为WebP格式(现代浏览器支持),兼顾压缩率与清晰度。
  4. Worker多线程优化:将计算密集型任务放入Web Worker,避免阻塞主线程。

2. 关键参数配置

3. 源代码实现示例

// 图片压缩函数(基于Canvas)
async function compressImage(file, quality = 0.7, maxWidthOrHeight= 1024) {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    
    reader.onload = (e) => {
      const img = new Image();
      img.src = e.target.result;
      
      img.onload = () => {
        const canvas = document.createElement('canvas');
        let width = img.width;
        let height = img.height;
        
        // 按比例缩放尺寸
        if (width > height) {
        	if (width > maxWidthOrHeight) {
        		width = maxWidthOrHeight;
	          height = Math.round((height * maxWidthOrHeight) / width);
	        }
        } else {
        	if (height > maxWidthOrHeight) {
	          width= Math.round((width* maxWidthOrHeight) / height);
	          height= maxWidthOrHeight;
	        }
        }
        
        canvas.width = width;
        canvas.height = height;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0, width, height);
        
        // 转换为WebP格式(或指定为'image/jpeg')
        canvas.toBlob(
          (blob) => resolve(blob),
          'image/webp',
          quality
        );
      };
    };
  });
}

// 使用示例
document.querySelector('input[type="file"]').addEventListener('change', async (e) => {
  const file = e.target.files[0];
  const compressedBlob = await compressImage(file);
  console.log('压缩后大小:', compressedBlob.size / 1024, 'KB');
});

总结 

到此这篇关于前端图片压缩方案学习的文章就介绍到这了,更多相关前端图片压缩方案内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文