Node реализует сжатие изображений

Node.js

1. Введение

разработан некоторое время назадЗагрузить изображения в плагин Qiniu Vscode, не хватало еще одной функции на тот момент: сжатие изображений, что в этот раз было окончательно решено; заодно и легаси баг был решен (редактор зависает, если в ссылке есть пробел), и теперь его можно рассматривать как плагин с полными функциями.Заинтересованные партнеры могут искать плагины в Vscodeupload-to-qiniuустановить.

Предварительный просмотр эффекта:

Во-вторых, изображения, сжатые узлом

Изначально предполагалось использоватьTinyPNGAPI реализует сжатие изображений, но, попробовав его, я обнаружил, что скорость сжатия очень низкая, и, похоже, это стоит денег, поэтому я решительно сдался. использовать вместо этогоimagemin.
Здесь яма: Потому чтоimageminВы не можете сжимать изображения напрямую, но вам нужно полагаться наimagemin-jpegtranа такжеimagemin-pngquant, но при установкеimagemin-pngquantЯ не могу установить ее, когда нахожу.Одна из причин в том, что эта библиотека реализована на основе некоторых базовых языков, поэтому ее нельзя установить напрямую, и на компьютер необходимо установить другую зависимость.libpng.
установить libpng
Вставьте адрес для прямой установки brew:zhuanlan.zhihu.com/p/90508170До тех пор, пока он сказал перед командой Nook, в основном вы можете установить ее. Наконец, мы снова казнилиbrew install libpng,Подожди покаlibpngПосле успешной установки устанавливаем его в проектimagemin-pngquantготов к установке.

Код для сжатия картинокСогласно требованию, мы определенно не хотим, чтобы он сжимал изображение и помещал его в папку, но нам нужно получить сжатый контент непосредственно в коде и загрузить его непосредственно в Qiniu. затем используйтеimagemin.buffer, этот метод получаетbufferобъект, сжатый, а затем возвращенный какbuffer, нам нужно только загрузить сжатый буфер напрямую в Qiniu, идея такая, вот реализация кода:


// 获取buffer
export const getBufferFromFile = (filePath: string): Promise<Buffer> => {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, function (err: any, res: any) {
      if (!err) {
        resolve(res)
      }
    })
  })
}


// 压缩图片,传入图片文件路径,通过getBufferFromFile方法转为buffer 后进行压缩
const imageGzip = async (loaclFile: string): Promise<any> => {
  const bufferFile = await getBufferFromFile(loaclFile)
  let res
  try {
    res = await imagemin.buffer(bufferFile, {
      plugins: [
        imageminJpegtran(),
        imageminPngquant({
          quality: [0.6, 0.8],
        }),
      ],
    })
  } catch (err) {
    console.log('error', err)
    res = null
  }
  return res
}

Таким образом, мы можем легко реализовать сжатие изображения. Теперь давайте перепишем его и загрузим в Qiniu: поскольку раньше сжатия не было, мы можем напрямую загрузить путь к файлу в Qiniu. После сжатия у нас есть только буфер, и мы нужно загрузить буфер в Qiniu. :
gzipImage ? 'putStream' : 'putFile', если мы получаем буфер, используем formUploader.putStream, иначе нам нужен только formUploader.putFile для загрузки

export const upImageToQiniu = async (
  loaclFile: string,
  cb: { (res: any): void; (arg0: any): void },
  upConfig: QiNiuUpConfig
) => {
  const config = new qiniu.conf.Config()
  const formUploader = new qiniu.form_up.FormUploader(config)
  const putExtra = new qiniu.form_up.PutExtra()
  const token = getToken(upConfig.accessKey, upConfig.secretKey, upConfig.scope)
  let gzipImage
  if (upConfig.gzip) {
    gzipImage = await imageGzip(loaclFile)
  }
  // 获取当前时间戳
  var key = new Date().getTime()
  // 上传调用方法
  const uploadFnName = gzipImage ? 'putStream' : 'putFile'
  // 上传内容
  const uploadItem = gzipImage ? bufferToStream(gzipImage) : loaclFile
  // 七牛上传
  formUploader[uploadFnName](
    token,
    key,
    uploadItem,
    putExtra,
    function (respErr: any, respBody: any, respInfo: any) {
      if (respErr) {
        throw respErr
      }

      if (respInfo.statusCode === 200) {
        const url = upConfig.domain + '/' + respBody.key
        cb(url)
      }
    }
  )
}

Теперь мы можем поэкспериментировать с эффектом:
Выберите изображение png на своем компьютере:После загрузки с помощью нашего плагина откройте ссылку, чтобы увидеть:Сжатие изображения прошло успешно

3. Решить устаревшие ошибки

При его использовании я обнаружил проблему, что иногда редактор внезапно застревал, позже я обнаружил, что причина была в том, что он застревал, когда в ссылке был пробел, и тогда другое содержимое при наведении не реагировало . Поэтому просто удалите пробел в строке наведения, а затем выполните следующий метод, чтобы получить ссылку:

// 当前行的文本内容
const currentLineText = document.lineAt(position).text.replace(/\s+/g, "")

4. Конец

Чтобы некоторые изображения не были слишком большими и медленно загружались при предварительном просмотре изображений при наведении, добавлены параметры кадрирования Qiniu, поэтому другие типы ссылок на изображения могут не просматриваться и будут медленно решаться позже ^ ^. Я загрузил исходный код плагина наgithub, добро пожаловать всем, чтобы нажать кнопку Пуск ^ ^. Если у вас есть лучшие идеи для плагинов, вы также можете общаться друг с другом.

Спасибо за чтение 🙏