You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在VSCode扩展中实现剪贴板图片的粘贴与上传功能?

实现VSCode扩展中剪贴板图片粘贴与上传的方案

由于VSCode官方API仅支持文本类剪贴板操作,要实现图片粘贴上传,需借助Electron底层能力和第三方工具完成,以下是具体实现步骤:

1. 读取剪贴板图片

VSCode基于Electron运行,可直接调用Electron的clipboard模块读取图片数据,无需额外安装依赖:

const { clipboard } = require('electron');
const fs = require('fs');
const path = require('path');

// 读取剪贴板图片
const image = clipboard.readImage();
if (image.isEmpty()) {
  vscode.window.showErrorMessage('剪贴板中无可用图片');
  return;
}
// 将图片转为Buffer并写入临时文件
const imageBuffer = image.toPNG();
const tempDir = path.join(context.extensionPath, 'temp');
if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir);
const tempPath = path.join(tempDir, `${Date.now()}.png`);
fs.writeFileSync(tempPath, imageBuffer);

若需更简化的跨平台处理,也可使用node-clipboard-image包(需执行npm install node-clipboard-image --save安装):

const clipboardImage = require('node-clipboard-image');

clipboardImage.saveImage({
  savePath: path.join(context.extensionPath, 'temp'),
  imageName: `${Date.now()}.png`
}).then(res => {
  // res.imgPath 即为临时文件路径,后续用于上传
}).catch(err => {
  vscode.window.showErrorMessage(`读取剪贴板图片失败:${err.message}`);
});

2. 实现图片上传逻辑

根据你选择的图床(如阿里云OSS、七牛云、Imgur等),调用对应SDK完成上传。以七牛云为例:

  1. 安装SDK:npm install qiniu --save
  2. 编写上传代码:
const qiniu = require('qiniu');

// 从VSCode配置中读取用户设置的图床信息
const config = vscode.workspace.getConfiguration('imageUpload');
const accessKey = config.get('accessKey');
const secretKey = config.get('secretKey');
const bucket = config.get('bucket');
const domain = config.get('domain');

// 生成上传凭证
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
const putPolicy = new qiniu.rs.PutPolicy({ scope: bucket });
const uploadToken = putPolicy.uploadToken(mac);

// 执行上传
const formUploader = new qiniu.form_up.FormUploader(new qiniu.conf.Config());
formUploader.putFile(uploadToken, null, tempPath, new qiniu.form_up.PutExtra(), (err, respBody) => {
  if (err) {
    vscode.window.showErrorMessage(`图片上传失败:${err.message}`);
    return;
  }
  // 上传成功后获取图片URL
  const imageUrl = `http://${domain}/${respBody.key}`;
  // 将URL插入到当前编辑器
  const editor = vscode.window.activeTextEditor;
  if (editor) {
    editor.edit(editBuilder => {
      editBuilder.insert(editor.selection.active, `![图片](${imageUrl})`);
    });
    vscode.window.showInformationMessage('图片上传成功');
  }
  // 清理临时文件
  fs.unlinkSync(tempPath);
});

3. 整合到VSCode扩展

注册命令与快捷键

在package.json中添加命令和快捷键绑定:

{
  "contributes": {
    "commands": [
      {
        "command": "image-upload.pasteAndUpload",
        "title": "粘贴并上传图片"
      }
    ],
    "keybindings": [
      {
        "command": "image-upload.pasteAndUpload",
        "key": "ctrl+v",
        "when": "editorTextFocus && !editorReadonly"
      }
    ]
  }
}

添加用户配置项

让用户可通过VSCode设置面板配置图床信息,在package.json中添加:

{
  "contributes": {
    "configuration": {
      "title": "图片上传配置",
      "properties": {
        "imageUpload.accessKey": {
          "type": "string",
          "description": "图床AccessKey"
        },
        "imageUpload.secretKey": {
          "type": "string",
          "description": "图床SecretKey"
        },
        "imageUpload.bucket": {
          "type": "string",
          "description": "存储空间名称"
        },
        "imageUpload.domain": {
          "type": "string",
          "description": "图床访问域名"
        }
      }
    }
  }
}

激活扩展命令

在extension.js中注册命令逻辑:

const vscode = require('vscode');
const { clipboard } = require('electron');
const fs = require('fs');
const path = require('path');
const qiniu = require('qiniu');

function activate(context) {
  const pasteUploadCmd = vscode.commands.registerCommand('image-upload.pasteAndUpload', async () => {
    // 读取剪贴板图片
    const image = clipboard.readImage();
    if (image.isEmpty()) {
      vscode.window.showErrorMessage('剪贴板中无可用图片');
      return;
    }
    const imageBuffer = image.toPNG();
    const tempDir = path.join(context.extensionPath, 'temp');
    if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir);
    const tempPath = path.join(tempDir, `${Date.now()}.png`);
    fs.writeFileSync(tempPath, imageBuffer);

    // 上传图片
    const config = vscode.workspace.getConfiguration('imageUpload');
    const accessKey = config.get('accessKey');
    const secretKey = config.get('secretKey');
    const bucket = config.get('bucket');
    const domain = config.get('domain');

    if (!accessKey || !secretKey || !bucket || !domain) {
      vscode.window.showErrorMessage('请先配置图床信息');
      fs.unlinkSync(tempPath);
      return;
    }

    const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
    const putPolicy = new qiniu.rs.PutPolicy({ scope: bucket });
    const uploadToken = putPolicy.uploadToken(mac);

    const formUploader = new qiniu.form_up.FormUploader(new qiniu.conf.Config());
    formUploader.putFile(uploadToken, null, tempPath, new qiniu.form_up.PutExtra(), (err, respBody) => {
      if (err) {
        vscode.window.showErrorMessage(`图片上传失败:${err.message}`);
        fs.unlinkSync(tempPath);
        return;
      }
      const imageUrl = `http://${domain}/${respBody.key}`;
      const editor = vscode.window.activeTextEditor;
      if (editor) {
        editor.edit(editBuilder => {
          editBuilder.insert(editor.selection.active, `![图片](${imageUrl})`);
        });
        vscode.window.showInformationMessage('图片上传成功');
      }
      fs.unlinkSync(tempPath);
    });
  });

  context.subscriptions.push(pasteUploadCmd);
}

function deactivate() {}

module.exports = { activate, deactivate };

关键注意事项

  • 临时文件清理:上传完成后必须删除临时文件,避免占用磁盘空间
  • 错误处理:覆盖剪贴板无图片、配置缺失、上传失败等场景,给用户明确提示
  • 跨平台兼容:Electron的clipboard模块在Windows、Mac、Linux平台均能正常工作
  • 权限管理:确保扩展拥有临时目录的读写权限

内容的提问来源于stack exchange,提问作者Ray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 12:15:27