前端实现图片压缩(干货总结)

2024-09-02 23:04

本文主要是介绍前端实现图片压缩(干货总结),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前端实现图片压缩方案总结

      • 前文提要
      • 1. 使用HTML5的`<canvas>`元素
        • 步骤概述:
        • 示例代码:
      • 2. 利用第三方库(推荐)
        • 使用 image-magic-adapter示例:
      • 3. gif图片压缩(拓展)
        • node压缩gif实现如下:
      • 注意事项


⚠️⚠️文前推荐一下👉
前端必备工具推荐网站(图床、API和ChatAI、智能AI简历、AI思维导图神器等实用工具):
站点入口:http://luckycola.com.cn/


前文提要

在Web开发中,图片压缩是一个常见且重要的需求。随着高清图片和多媒体内容的普及,如何在保证图片质量的同时减少其文件大小,对于提升网页加载速度、优化用户体验至关重要。前端作为用户与服务器之间的桥梁,实现图片压缩的功能可以显著减轻服务器的负担,加快页面渲染速度。本文将探讨前端实现图片压缩的几种方法和技术。

1. 使用HTML5的<canvas>元素

HTML5的<canvas>元素为前端图片处理提供了强大的能力。通过JavaScript操作<canvas>,我们可以读取图片数据,对其进行处理(如缩放、裁剪、转换格式等),然后输出压缩后的图片。

步骤概述:
  1. 读取图片:使用FileReaderImage对象加载图片。
  2. 绘制到<canvas>:将图片绘制到<canvas>上,通过调整<canvas>的尺寸或绘图参数来控制压缩效果。
  3. 导出图片:使用canvas.toDataURL()方法将<canvas>内容转换为Base64编码的图片,或使用canvas.toBlob()方法获取Blob对象,以便进一步处理或上传。
示例代码:
function compressImage(file, quality, callback) {const reader = new FileReader();reader.onload = function(e) {const img = new Image();img.onload = function() {const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');// 设置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;ctx.drawImage(img, 0, 0, width, height);// 转换为压缩后的图片canvas.toBlob(function(blob) {callback(blob);}, 'image/jpeg', quality);};img.src = e.target.result;};reader.readAsDataURL(file);
}// 使用示例
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', function(e) {const file = e.target.files[0];compressImage(file, 0.7, function(blob) {// 处理压缩后的图片,如上传或显示console.log(blob);});
});

2. 利用第三方库(推荐)

除了原生JavaScript和HTML5外,还有许多优秀的第三方库可以帮助我们更方便地实现图片压缩,如image-magic-adapter、compressorjspica等。这些库通常提供了更丰富的配置选项和更好的兼容性支持。

特别推荐的库: image-magic-adapter
这个三方库是国内开发者提供的,他集成许多图片处理能力,包括“图片压缩”、“图片格式转换”、“图片加水印”等等,非常方便,而且这个库还有官网也可以直接使用这些功能.

库官网:https://www.npmjs.com/package/image-magic-adapter

在线图片处理工具官网:https://luckycola.com.cn/public/dist/imageTool.html

使用 image-magic-adapter示例:
// 引入image-magic-adapter
import ImageMagicAdapter from 'image-magic-adapter';
let ImageCompressorCls = ImageMagicAdapter.ImageCompressorCls;const imageCompressor = new ImageCompressorCls(); // 默认压缩质量// -----------------------------------------图片压缩-----------------------------------------document.getElementById('quality').addEventListener('input', () => {const quality = parseFloat(document.getElementById('quality').value);imageCompressor.quality = 1 - quality; // 更新压缩质量console.log('更新后的压缩质量:', imageCompressor.quality);});document.getElementById('compress').addEventListener('click', async () => {const fileInput = document.getElementById('upload');if (!fileInput.files.length) {alert('请上传图片');return;}const files = Array.from(fileInput.files);const progress = document.getElementById('progress');const outputContainer = document.getElementById('outputContainer');const downloadButton = document.getElementById('download');const progressText = document.getElementById('progressText');outputContainer.innerHTML = '';downloadButton.style.display = 'none';progress.style.display = 'block';progress.value = 0;progressText.innerText = '';// compressImages参数说明://  第一个参数: files:需要压缩的文件数组//  第二个参数: callback:压缩完成后的回调函数//  第三个参数: 若是压缩png/bmp格式,输出是否保留png/bmp格式,默认为true(建议设置为false)// 注意:如果 第三个参数设置true压缩png/bmp格式后的输出的文件为原格式(png/bmp)且压缩效果不佳,就需要依赖设置scaleFactor来调整压缩比例(0-1);如果设置为false,输出为image/jpeg格式且压缩效果更好。// 设置caleFactor为0-1,值越大,压缩比例越小,值越小,压缩比例越大(本质是改变图片的尺寸),例: imageCompressor.scaleFactor = 0.5;await imageCompressor.compressImages(files, (completed, total) => {const outputImg = document.createElement('img');outputImg.src = imageCompressor.compressedImages[completed - 1];outputContainer.appendChild(outputImg);progress.value = (completed / total) * 100;progressText.innerText = `已完成文件数: ${completed} / 总文件数: ${total}`;if (completed === total) {downloadButton.style.display = 'inline-block';}}, false);downloadButton.onclick = () => {if (imageCompressor.compressedImages.length > 0) {imageCompressor.downloadZip(imageCompressor.compressedImages);}};});
<h4>图片压缩Demo</h4><input type="file" id="upload" accept="image/*" multiple /><br><label for="quality">压缩比率:(比率越大压缩越大,图片质量越低)</label><input type="range" id="quality" min="0" max="0.9" step="0.1" required value="0.5"/><br><button id="compress">压缩图片</button><br><progress id="progress" value="0" max="100" style="display: none;"></progress><br /><span id="progressText"></span><br><div id="outputContainer"></div><br><button id="download" style="display: none;">下载已压缩图片</button>

3. gif图片压缩(拓展)

GIF(Graphics Interchange Format)图片是一种广泛使用的图像文件格式,特别适合用于显示索引颜色图像(如简单的图形、图标和某些类型的图片),同时也支持动画。尽管GIF图片本身可以具有压缩特性,但在前端和后端进行压缩处理时,存在几个关键考虑因素,这些因素可能导致在前端直接压缩GIF不如在后端处理更为有效或合理。

下面提供一个厚后端通过node实现gif压缩的方案:
1、下载imagemin、imagemin-gifsicle和image-size库
2、注意依赖的库的版本,不然可能会报错

	"image-size": "^1.1.1","imagemin": "7.0.1","imagemin-gifsicle": "^7.0.0",
node压缩gif实现如下:

const imagemin = require('imagemin');
const imageminGifsicle = require('imagemin-gifsicle');
const sizeOf = require('image-size');// 压缩 GIF colors[0-256]
const compressGifImgFn = async (inputBase64, colors = 200, successFn = () => {}, failFn = () => {}) => {try {if (inputBase64.length <= 10) {failFn && failFn('inputBase64 无效')return;}// 获取输入 GIF 的尺寸const originalSize = getBase64Size(inputBase64);console.log('Original Size:', originalSize);// 转换 Base64 为 Bufferconst inputBuffer = base64ToBuffer(inputBase64);const outputBuffer = await imagemin.buffer(inputBuffer, {plugins: [imageminGifsicle({// interlaced的作用 是,是否对 GIF 进行隔行扫描interlaced: true,// optimizationLevel的作用是,设置压缩的质量,0-3optimizationLevel: 3,// // progressive的作用是,是否对 GIF 进行渐进式压缩// progressive: true,// // palette的作用是,是否对 GIF 进行调色板优化// palette: true,// // colorspace的作用是,是否对 GIF 进行色彩空间转换// colorspace: true,colors})]});// 转换压缩后的 Buffer 为 Base64const outputBase64 = bufferToBase64(outputBuffer);// 获取压缩后 GIF 的尺寸const compressedSize = getBase64Size(outputBase64);console.log('Compressed Size:', compressedSize);// 输出压缩后的 Base64 GIF// console.log(outputBase64);let gifCompressRes =  {outputBase64,compressedSize,originalSize}successFn && successFn(gifCompressRes);} catch (error) {console.error('Error compressing GIF:', error);failFn && failFn(error)}
};// 将 Base64 字符串转换为 Buffer
function base64ToBuffer(base64) {const base64Data = base64.split(',')[1]; // 如果是 data URL, 删除前缀return Buffer.from(base64Data, 'base64');
}// 将 Buffer 转换为 Base64 字符串
function bufferToBase64(buffer) {return `data:image/gif;base64,${buffer.toString('base64')}`;
}//获取base64图片大小,返回kb数字
function getBase64Size(base64url) {try {//把头部去掉let str = base64url.replace('data:image/png;base64,', '');// 找到等号,把等号也去掉let equalIndex = str.indexOf('=');if (str.indexOf('=') > 0) {str = str.substring(0, equalIndex);}// 原来的字符流大小,单位为字节let strLength = str.length;// 计算后得到的文件流大小,单位为字节let fileLength = parseInt(strLength - (strLength / 8) * 2);// 由字节转换为kblet size = "";size = (fileLength / 1024).toFixed(2);let sizeStr = size + ""; //转成字符串let index = sizeStr.indexOf("."); //获取小数点处的索引let dou = sizeStr.substr(index + 1, 2) //获取小数点后两位的值if (dou == "00") { //判断后两位是否为00,如果是则删除00                return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2)}return size;} catch (error) {console.log('getBase64Size error:', error);return 0;}};

注意事项

  • 压缩质量与文件大小:压缩质量越高,图片质量越好,但文件大小也越大;反之亦然。需要根据实际需求调整。
  • 兼容性:虽然现代浏览器普遍支持<canvas>和Blob等特性,但在一些老旧浏览器上可能存在问题,需要做好兼容性处理。
  • 性能考虑:对于大图片或高频率的图片处理,前端压缩可能会占用较多CPU资源,影响页面性能。

这篇关于前端实现图片压缩(干货总结)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131321

相关文章

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

全面解析HTML5中Checkbox标签

《全面解析HTML5中Checkbox标签》Checkbox是HTML5中非常重要的表单元素之一,通过合理使用其属性和样式自定义方法,可以为用户提供丰富多样的交互体验,这篇文章给大家介绍HTML5中C... 在html5中,Checkbox(复选框)是一种常用的表单元素,允许用户在一组选项中选择多个项目。本

HTML5 搜索框Search Box详解

《HTML5搜索框SearchBox详解》HTML5的搜索框是一个强大的工具,能够有效提升用户体验,通过结合自动补全功能和适当的样式,可以创建出既美观又实用的搜索界面,这篇文章给大家介绍HTML5... html5 搜索框(Search Box)详解搜索框是一个用于输入查询内容的控件,通常用于网站或应用程

Python实现精准提取 PDF中的文本,表格与图片

《Python实现精准提取PDF中的文本,表格与图片》在实际的系统开发中,处理PDF文件不仅限于读取整页文本,还有提取文档中的表格数据,图片或特定区域的内容,下面我们来看看如何使用Python实... 目录安装 python 库提取 PDF 文本内容:获取整页文本与指定区域内容获取页面上的所有文本内容获取

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

CSS3中的字体及相关属性详解

《CSS3中的字体及相关属性详解》:本文主要介绍了CSS3中的字体及相关属性,详细内容请阅读本文,希望能对你有所帮助... 字体网页字体的三个来源:用户机器上安装的字体,放心使用。保存在第三方网站上的字体,例如Typekit和Google,可以link标签链接到你的页面上。保存在你自己Web服务器上的字