Skip to content

Nest 图片压缩

安装包

bash
pnpm install sharp

创建一个 controller

流程

  • 用户上传

  • 上传成功后你读取上传的文件变成 2 进制

  • 使用 sharp 压缩图片

  • 压缩成功后返回图片地址

代码

第一种

压缩返回本地路径

ts
import { Observable } from 'rxjs';
import type { Response } from 'express';
import { join } from 'path';
import { writeFile, writeFileSync } from 'fs';

const sharp = require('sharp');
const axios = require('axios');
  // 图片压缩 返回本地路径
  @Get('yasuo')
  async yasuo(@Query() query: any) {
    console.log(query.url);

    const response = await fetch(query.url);
    const buffer = await response.arrayBuffer();

    const data = await sharp(Buffer.from(buffer))
      .webp({ quality: 80 })
      .toBuffer();

    const uploadsDir = join(process.cwd(), 'uploads');

    const filePath = join(uploadsDir, '2.png');

    await writeFileSync(filePath, data);

    return {
      data: {
        imgsrc: 'http://localhost:5000/' + 'uploads/2.png',
      },
    };
  }

第二种

压缩返回 base64 前端在自己下载

ts
import { Observable } from "rxjs";
import type { Response } from "express";
import { join } from "path";
import { writeFile, writeFileSync } from "fs";

const sharp = require("sharp");
const axios = require("axios");
  // 第二种直接返回数据流前端就下载了
  @Get('yasuo2')
  async yasuo2(@Query() query: any, @Res() res: Response) {
    console.log(query.url);

    const response = await fetch(query.url);
    const buffer = await response.arrayBuffer();

    const data = await sharp(Buffer.from(buffer)).webp().toBuffer();

    res.setHeader('Content-Type', 'image/webp');
    res.send(data);
  }
  • 前端下载
html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>下载压缩图片</title>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <div onclick="downland()">下载</div>
    <script>
      const downland = async () => {
        console.log("点击了啊");
        const res = await axios.get(
          "http://localhost:5000/user/yasuo2?url=https://xxxx/2.png",
          {
            responseType: "arraybuffer",
          }
        );

        const blob = new Blob([res.data], { type: "image/jpeg" });
        const url = URL.createObjectURL(blob);
        const link = document.createElement("a");
        link.href = url;
        link.download = "3.png";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);

        // 清理 URL 对象
        window.URL.revokeObjectURL(url);
      };
    </script>
  </body>
</html>