I. Brief introduction

Some time ago, I developed the Vscode plug-in for uploading pictures to Qiniu. At that time, there was still a function missing: picture compression, which was finally solved this time. Also solved a legacy bug (the editor would get stuck in the link with Spaces), now it can be considered a fully functional plug-in, interested friends can search the upload to qiniu plug-in in Vscode to install.

Effect preview:

2. Node compresses images

At first, I was going to use TinyPNG’s API to compress images, but after trying it out, I found that the compression speed was very slow and seemed to cost a lot of money, so I gave up. Use imagemin instead. Here is a pit: Since imagemin cannot compress images directly, it relies on Imagemin-JpegTran and Imagemin-PngQuant, which cannot be installed when imagemin-PngQuant is installed. One reason is that the library is implemented in some underlying language. So you can’t install it directly, you need to install another dependency libpng on your computer. Install libpng directly stick a brew installation address: zhuanlan.zhihu.com/p/90508170, as long as the said to his command basically can install the brew. Brew install libpng. After libpng is successfully installed, imagemin-pngquant can be installed in the project.

According to the requirements, we certainly do not want him to compress the picture in the folder, but need to obtain the compressed content directly in the code, directly uploaded to the seven cattle. Buffer. This method receives a buffer object, compresses it, and then returns a buffer. We just upload the compressed buffer directly to the seven cows.


/ / for 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) } }) }) }// Compress the image, pass the image file path, use getBufferFromFile method to buffer after compression
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
}

Copy the code

Since there is no compression before, we can directly upload the file path to qox. After compression, we only have buffer. We need to upload the buffer to qox: gzipImage? ‘putStream’ : ‘putFile’, formuploader.putStream is used if we get buffer, otherwise formuploader.putFile is uploaded

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)
  }
  // Get the current timestamp
  var key = new Date().getTime()
  // Upload the call method
  const uploadFnName = gzipImage ? 'putStream' : 'putFile'
  // Upload content
  const uploadItem = gzipImage ? bufferToStream(gzipImage) : loaclFile
  // Upload the file
  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)
      }
    }
  )
}
Copy the code

Now we can try it out:

Select a PNG image on your computer:After uploading with our plugin, open the link to see:Image compression succeeded ~ ~

Solve the remaining bugs

When using it, I found a problem that sometimes the editor would suddenly become stuck. Later, I found that the reason was that it would be stuck when there was a space in the link, and then other hover contents did not respond. So remove the hover string space and then perform the following link method can be:

// The text content of the current line
const currentLineText = document.lineAt(position).text.replace(/\s+/g."")
Copy the code

Fourth, the end

Because the hover preview in order to prevent some images too slow loading, add seven cattle cropping parameters, so other types of links may not be able to preview, later will be solved slowly. I have uploaded the plugin source code to Github. Please click Start ^ ^. If you have better ideas for plug-ins, you can also exchange them.

Thanks for reading 🙏