JS 图片压缩原理与实现方法详解

yizhihongxing

JS 图片压缩原理与实现方法详解

原理介绍

图片压缩是指在保证图片质量的前提下,通过降低图片的分辨率、压缩比率等方式来减小图片的体积,从而达到优化页面加载速度的目的。在网页中,对于图片的大小不同,会直接影响页面的加载速度,特别是对于移动端的用户体验更加重要。

在实现 JavaScript 图片压缩的时候,常见的有两种方式:

  • HTML5 的 Canvas + toDataURL 方法;

  • JavaScript 的 atob 和 btoa 方法。

其中,在使用 Canvas + toDataURL 方法时,通过将图片加载到 Canvas 画布上面,再将 Canvas 转为 base64 编码的字符串,并通过“压缩比”设置实现图片压缩。

而在使用 atob 和 btoa 方法时,通过利用浏览器提供的 atob 和 btoa 方法,将原图片数据转换成二进制数据,并通过设置“压缩比”实现游览器端图片压缩。

实现步骤

方式一:Canvas + toDataURL

1. 加载图片到 Canvas 画布中

var img = new Image();
img.src = 'original.jpg';
img.onload = function() {
  var canvas = document.createElement('canvas');
  var ctx = canvas.getContext('2d');
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.drawImage(img, 0, 0, img.width, img.height);
}

2. Canvas 转为 base64 编码的字符串

var quality = 0.6; // 压缩比例
var dataURL = canvas.toDataURL('image/jpeg', quality); // 转为 JPEG 格式

方式二:atob 和 btoa

1. 将图片读取为二进制数据

// 读取图片的原始数据
var xhr = new XMLHttpRequest();
xhr.open('GET', 'original.jpg', true);
xhr.responseType = 'blob';
xhr.onload = function() {
  if (xhr.status === 200) {
    var reader = new FileReader();
    reader.onload = function(e) {
      var dataUrl = e.target.result;
      // dataUrl 经过 btoa 后压缩比变化
      var compressedDataURL = _compressImg(dataUrl, 0.6);
    }
    reader.readAsDataURL(xhr.response);
  }
};
xhr.send();

2. 将二进制数据转为 base64 编码的字符串

function _compressImg(dataUrl, quality) {
  var img = new Image();
  img.src = dataUrl;
  var canvas = document.createElement('canvas');
  var ctx = canvas.getContext('2d');
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.drawImage(img, 0, 0, img.width, img.height);
  var imageData = canvas.toDataURL('image/jpeg', quality);
  return imageData;
}

示例说明

示例一

假设我们有一张 2000 x 2000 像素的图片,使用方式一压缩图片,并设置压缩比为 0.6,代码如下:

var img = new Image();
img.src = 'original.jpg';
img.onload = function() {
  var canvas = document.createElement('canvas');
  var ctx = canvas.getContext('2d');
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.drawImage(img, 0, 0, img.width, img.height);

  var quality = 0.6; // 压缩比例
  var dataURL = canvas.toDataURL('image/jpeg', quality); // 转为 JPEG 格式

  console.log('原始图片大小:', img.src.length);
  console.log('压缩后图片大小:', dataURL.length);
};

输出结果为:

原始图片大小: 1588163
压缩后图片大小: 275235

可以看到使用该方法可以达到将图片体积减小到原始大小的 17% 左右。

示例二

假设我们有一张 4000 x 4000 像素的图片,使用方式二压缩图片,并设置压缩比为 0.4,代码如下:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'original.jpg', true);
xhr.responseType = 'blob';
xhr.onload = function() {
  if (xhr.status === 200) {
    var reader = new FileReader();
    reader.onload = function(e) {
      var dataUrl = e.target.result;
      // dataUrl 经过 btoa 后压缩比变化
      var compressedDataURL = _compressImg(dataUrl, 0.4);

      console.log('原始图片大小:', dataUrl.length);
      console.log('压缩后图片大小:', compressedDataURL.length);
    }
    reader.readAsDataURL(xhr.response);
  }
};
xhr.send();

function _compressImg(dataUrl, quality) {
  var img = new Image();
  img.src = dataUrl;
  var canvas = document.createElement('canvas');
  var ctx = canvas.getContext('2d');
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.drawImage(img, 0, 0, img.width, img.height);
  var imageData = canvas.toDataURL('image/jpeg', quality);
  return imageData;
}

输出结果为:

原始图片大小: 4699401
压缩后图片大小: 881580

可以看到使用该方法可以达到将图片体积减小到原始大小的 19% 左右。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS 图片压缩原理与实现方法详解 - Python技术站

(1)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • 详解Vue中数组和对象更改后视图不刷新的问题

    下面是讲解”详解Vue中数组和对象更改后视图不刷新的问题”的攻略。 问题背景 在Vue中,当我们通过改变数组或对象的属性来更新数据时,Vue并不会立即将这个变化反映到视图上,而需要一些特殊的方法才能实现视图的更新。 解决方案 Vue提供了一些响应式的API来检测数据的变化,我们可以使用这些API来解决这个问题。 数组 当我们需要改变数组数据时,可以用以下几种…

    Vue 2023年5月29日
    00
  • vue实现移动端拖动排序

    下面我将为您详细讲解“vue实现移动端拖动排序”的完整攻略。 1. 安装vue相关依赖 首先需要安装vue相关依赖,包括vue本身以及vue移动端手势库vue-touch。 npm install vue –save npm install vue-touch@next –save 2. 引入vue相关依赖 在你的vue项目入口文件中引入vue及vue-…

    Vue 2023年5月29日
    00
  • 17个vue常用的数组方法总结与实例演示

    我们来详细讲解一下“17个vue常用的数组方法总结与实例演示”的完整攻略。 一、前言 在Vue中,我们经常需要操作数组。而对于数组的操作,Vue提供了许多方便快捷的方法。本文将对Vue中17个常用的数组方法进行总结和实例演示,方便大家学习和使用。 二、数组方法 1. push 向数组添加一个或多个元素,并返回新的长度。 let arr = [1,2,3]; …

    Vue 2023年5月27日
    00
  • React中props使用教程

    React中props使用教程 在React中,props是组件间通信的主要方式之一。通过props,我们可以将数据从一个组件传递到另一个组件。本教程将详细讲解props的使用方法。 什么是props props(即“properties”,中文翻译为“属性”)是组件中的一种数据传递机制。通过props,我们可以向组件传递数据,就像向函数传递参数一样。pro…

    Vue 2023年5月28日
    00
  • vue项目中自动导入svg并愉快的使用方式

    Vue项目中自动导入SVG并愉快的使用方式的攻略需要涉及到以下几个步骤: 1. 安装相关依赖 svg-sprite-loader:用于对SVG进行打包处理,将SVG图标精灵化。 svgo-loader:对SVG进行压缩和优化,减少SVG的文件大小。 npm install svg-sprite-loader svgo-loader -D 2. 配置webpa…

    Vue 2023年5月28日
    00
  • Vue2如何支持composition API示例详解

    请看下面的完整攻略,分为以下几个部分: 简介 Composition API 是 Vue3 引入的一个全新的 API 风格,可以提供一些更高级的组合逻辑。而 Vue2 与 Vue3 语法有所不同,不直接支持 Composition API。但是,如果你使用 Vue2,也可以通过安装@vue/composition-api 来使用这个 API。 安装 Vue …

    Vue 2023年5月28日
    00
  • vue+el-upload实现多文件动态上传

    要实现多文件动态上传,我们可以使用Vue.js提供的el-upload组件来实现。下面是实现此功能的具体步骤: 步骤1:安装el-upload npm install element-ui -S 步骤2:导入el-upload组件 在Vue组件中导入el-upload组件。在main.js文件中引入element-ui: import Vue from ‘v…

    Vue 2023年5月28日
    00
  • Vue组件的渲染流程详细讲解

    请先了解Vue组件渲染的基本流程: 解析模板:Vue会解析组件模板中的所有内容,包括HTML标记、CSS样式和JavaScript交互代码等。 创建VNode:解析完模板后,Vue会根据解析出来的数据创建一个虚拟节点(Virtual Node)。 创建组件实例:根据VNode创建组件实例,Vue会在实例化组件时对其进行一些具体的属性、数据等等进行初始化。 渲…

    Vue 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部