堪比tinify的图片压缩工具TinyPNG

介绍

  • 基于tinypng的图片压缩工具,支持图片压缩功能。
  • 使用客户端压缩图片,无需上传到服务器,直接在客户端进行压缩。
  • 支持WebWork
  • npm:tinypng-lib
  • 在线体验地址:tinypng.wcrane.cn/

使用方法

  • 安装
shell 复制代码
npm install tinypng-lib
  • 基本使用
html 复制代码
<template>
  <div id="app">
    <input type="file" @input="uploadImg" />
    <img :src="imgUrl" alt="">
  </div>
</template>
​
<script>
import TinyPNG from 'tinypng-lib'
​
​
export default {
  name: 'App',
  components: {
  },
  data() {
    return {
      imgUrl: ''
    }
  },
  methods: {
    async uploadImg(e) {
      const file = e.target.files[0];
      try {
        const res = await TinyPNG.compress(file, {})
        console.log('res', res)
        const url = URL.createObjectURL(res.blob)
        const img = new Image()
        this.imgUrl = url
      } catch (error) {
        console.log("error", error)
      }
​
    }
  }
}
</script>

参数说明

参数 说明 默认值
minimumQuality 最小质量 35
quality 期望压缩质量(0-100) 88
fileName 压缩后的文件名 文件名称
js 复制代码
/**
 * 压缩图片参数
 */
interface CompressOptions {
    minimumQuality?: number; // 最小质量
    quality?: number; // 压缩质量 0 - 100
    fileName?: string; // 压缩后的文件名, 默认为file.name
}
​

返回值说明

js 复制代码
/**
 * 压缩图片结果
 */
interface CompressResult {
    success: boolean, // 是否成功
    file: File, // 压缩后的文件
    originalSize: number, // 原始文件大小
    compressedSize: number, // 压缩后文件大小
    rate: number, // 压缩率(压缩为原来的%)
    output: ArrayBuffer, // 压缩后的 ArrayBuffer
    blob: Blob, // 压缩后的 Blob
    rateString: string, // 压缩率字符串
}

WebWorker中使用

基本使用

  1. webpack项目中安装worker-loader
shell 复制代码
npm install worker-loader
  1. webpack.config.js中配置
js 复制代码
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /.worker.js$/,
        use: { loader: 'worker-loader' },
      },
    ],
  },
};
  1. 定义imageWorker.worker.js
js 复制代码
// imageWorker.worker.js
import TinyPNG from 'tinypng-lib';
self.onmessage = async function (e) {
    const {
        image,
        options
    } = e.data;
    try {
        // 使用支持webWorker的方法
        const result = await TinyPNG.compressWorkerImage(image, options);
        self.postMessage(result);
    } catch (error) {
        self.postMessage({ error: error.message });
    }
};
  1. 在组件中使用
  • 监听webworker的消息
  • 使用 TinyPNG.getImage 处理文件信息
  • 发送图片信息给webworker进行压缩
  • 接收webworker返回的压缩结果
js 复制代码
<script>
// Import the worker
import ImageWorker from './imageWorker.worker.js'; // This is the bundled worker
import { getSizeTrans } from '../utils';
import TinyPNG from 'tinypng-lib';
export default {
  name: 'Base',
  mounted() {
    // Start the worker when the component is mounted
    this.worker = new ImageWorker();
​
    // Receive the message (compressed result) from the worker
    this.worker.onmessage = (e) => {
      this.compressing = false;
      const result = e.data;
      if (result.error) {
        console.error("Compression failed:", result.error);
      } else {
        // 拿到压缩结果
        console.log(e);
      }
    };
  },
  methods: {
    getSizeTrans,
    async uploadImg(e) {
      const file = e.file;
      // 获取图片信息
      const image = await TinyPNG.getImage(file);
      // Send the file to the worker for compression
      this.worker.postMessage({
        image,
        options: {
          minimumQuality: 30,
          quality: 85
        }
      });
    }
  },
  beforeDestroy() {
    // Terminate the worker when the component is destroyed
    if (this.worker) {
      this.worker.terminate();
    }
  }
}
</script>
​
  1. 说明:对于jpeg、jpg的图片不支持使用WebWorker压缩需要使用TinyPNG.compressJpegImage 进行压缩
js 复制代码
import TinyPNG from 'tinypng-lib';
TinyPNG.compressJpegImage(file, options)

CompressWorker 使用

  • 封装代码
js 复制代码
import ImageWorker from './imageWorker.worker.js'; // 与前面imageWorker.worker.js一致
export class CompressWorker {
    worker = null;
    constructor() {
        this.worker = new ImageWorker();
    }
    async compress(file, options) {
        // 获取图片信息
        const image = await TinyPNG.getImage(file);
        return new Promise((resolve, reject) => {
            // 监听worker的消息
            this.worker.onmessage = (e) => {
                const result = e.data;
                if (result.error && !result.success) {
                    console.error("Compression failed:", result.error);
                    reject(result.error);
                } else {
                    resolve(result);
                }
            };
            // Send the file to the worker for compression
            this.worker.postMessage({
                image,
                options
            });
​
        });
    }
​
    terminate() {
        if (this.worker) {
            this.worker.terminate();
            this.worker = null;
        }
​
    }
}
​
  • 使用

    • 实例化:CompressWorker只注册一次就行,比如vue的mounted生命周期
    • 图片压缩
    • 页面或者组件卸载的时候执行, 销毁 CompressWorker 实例
js 复制代码
// 1. 只注册一次就行,比如vue的mounted生命周期
compressWorker = new CompressWorker();
​
// 2. 监听选择的图片,图片压缩
compressWorker.compress(file, {
  minimumQuality: 30,
  quality: 85
}).then((result) => {
  // 压缩结果
  console.log(result);
})
​
// 3. 页面或者组件卸载的时候执行, 销毁webworker
if (compressWorker) {
  compressWorker.terminate();
}

注意事项

  • 请确保已经安装了tinypng-lib模块
相关推荐
Mr_Xuhhh41 分钟前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
永乐春秋2 小时前
WEB攻防-通用漏洞&文件上传&js验证&mime&user.ini&语言特性
前端
鸽鸽程序猿2 小时前
【前端】CSS
前端·css
ggdpzhk2 小时前
VUE:基于MVVN的前端js框架
前端·javascript·vue.js
学不会•4 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
活宝小娜6 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点6 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow6 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o6 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic7 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端