本文将带你从零开始,一步步开发一个实用的VS Code插件——图片取色工具,让你在VS Code中轻松提取图片的主色调!
🚀 项目概述
起因:之前想基于凡人动漫制作一款主题,于是截了很多动漫的图片想提取这些图片的主色调色号,在网上找了很多小工具,基本都是只能一张一张上传图片生成结果,实在太费事了,于是就想着把这个功能做成一个VSCode插件。
这个插件应该具备以下功能:
- 📸 在资源管理器中右键图片文件
- 🎨 自动提取图片主色调生成色卡
- 📋 支持一键复制色号(HEX/RGB格式)
- ⚙️ 可配置色卡数量(6/8/10个颜色)
📋 开发环境准备
必备工具
# 安装Node.js和npm
# 安装VS Code
# 安装Yeoman和VS Code扩展生成器
npm install -g yo generator-code
创建项目
# 使用脚手架创建项目
yo code
# 选择配置:
# ? What type of extension do you want to create? New Extension (TypeScript)
# ? What's the name of your extension? Image Color Palette
# ? What's the identifier of your extension? image-color-palette
# ? What's the description of your extension? 从图片中提取主色调并生成色卡
# ? Initialize a git repository? Yes
# ? Bundle the source code with webpack? Yes
# ? Package manager to use? npm
🏗️ 项目结构设计
生成的项目结构:
image-color-palette/
├── src/
│ ├── extension.ts # 主扩展逻辑
│ └── test/
├── media/ # 静态资源
│ ├── paletteView.js # Webview前端脚本
│ └── palette.css # 样式文件
├── resources/ # 图标资源
│ └── icon.png
├── package.json # 扩展配置
├── webpack.config.js # 打包配置
└── tsconfig.json # TypeScript配置
📝 第一步:配置package.json
这是插件的"身份证",定义插件的基本信息和功能:
⚠️注意:publisher字段的值要和你注册Visual Studio Code Marketplace的Publisher ID保持一致,不然会发布失败
{
"name": "image-color-palette",
"displayName": "Image Color Palette|图片取色",
"description": "从图片中提取主色调并生成色卡,支持复制色号",
"version": "0.0.1",
"publisher": "CarrieXin",
"engines": {
"vscode": "^1.74.0"
},
"categories": ["Other"],
"main": "./dist/extension.js",
"icon": "./resources/icon.png",
"contributes": {
"commands": [
{
"command": "image-color-palette.generatePalette",
"title": "生成图片色卡"
}
],
"menus": {
"explorer/context": [
{
"command": "image-color-palette.generatePalette",
"group": "navigation@100",
"when": "resourceExtname == .png || resourceExtname == .jpg || resourceExtname == .jpeg || resourceExtname == .gif || resourceExtname == .webp || resourceExtname == .bmp || resourceExtname == .svg"
}
]
}
}
}
🔑 关键配置说明:
- contributes.commands: 定义插件提供的命令
- contributes.menus: 配置右键菜单显示位置
- when条件: 只在图片文件上显示菜单项
🎯 第二步:实现核心扩展逻辑
在src/extension.ts中实现主要功能:
import * as vscode from "vscode";
// 支持的图片扩展名
const IMAGE_EXTS = [".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp", ".svg"];
/**
* 激活扩展入口
* @param {vscode.ExtensionContext} context 扩展上下文
* @return {void} 无返回
*/
export function activate(context: vscode.ExtensionContext) {
console.log('插件"image-color-palette"已激活!');
// 注册生成图片色卡命令
const genPalette = vscode.commands.registerCommand(
"image-color-palette.generatePalette",
async (resource: vscode.Uri) => {
try {
const target = await ensureTargetImage(resource);
if (!target) {
return;
}
openPaletteWebview(context, target);
} catch (err: any) {
vscode.window.showErrorMessage(
`生成图片色卡失败: ${err?.message || String(err)}`
);
}
}
);
context.subscriptions.push(genPalette);
}
🖼️ 第三步:创建Webview界面
/**
* 打开色卡预览Webview
* @param {vscode.ExtensionContext} context 扩展上下文
* @param {vscode.Uri} imgUri 图片URI
* @return {void} 无返回
*/
function openPaletteWebview(
context: vscode.ExtensionContext,
imgUri: vscode.Uri
): void {
// 创建并显示webview面板
const panel = vscode.window.createWebviewPanel(
"imageColorPalette",
"图片色卡",
vscode.ViewColumn.Beside,
{
enableScripts: true,
retainContextWhenHidden: true,
}
);
// 处理webview消息
panel.webview.onDidReceiveMessage(
(message) => {
switch (message.type) {
case "copy":
vscode.env.clipboard.writeText(message.hex);
vscode.window.showInformationMessage(`已复制色号: ${message.hex}`);
break;
case "copyAll":
vscode.env.clipboard.writeText(message.colors.join("\n"));
vscode.window.showInformationMessage(
`已复制${message.colors.length}个色号`
);
break;
}
},
undefined,
context.subscriptions
);
🎨 第四步:实现前端色彩提取算法
在media/paletteView.js中实现K-Means聚类算法提取主色调:
/**
* 图片色卡生成器
* 作者:CarrieXin
* 功能:使用K-Means算法从图片中提取主色调
*/
class ColorPalette {
constructor() {
this.vscode = acquireVsCodeApi();
this.init();
}
/**
* 初始化色卡生成器
*/
init() {
const img = document.getElementById('sourceImage');
img.onload = () => {
this.extractColors(img);
};
}
/**
* 使用K-Means算法提取图片主色调
* @param {HTMLImageElement} img 图片元素
*/
extractColors(img) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// 设置画布尺寸
canvas.width = img.width;
canvas.height = img.height;
// 绘制图片到画布
ctx.drawImage(img, 0, 0);
// 获取图片像素数据
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const pixels = this.getPixels(imageData);
// 使用K-Means聚类提取主色调
const colorCount = parseInt(document.getElementById('colorCount').value);
const dominantColors = this.kMeans(pixels, colorCount);
// 渲染色卡
this.renderPalette(dominantColors);
}
/**
* RGB转HEX
* @param {number} r 红色值
* @param {number} g 绿色值
* @param {number} b 蓝色值
* @return {string} HEX颜色值
*/
rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
}
// 初始化色卡生成器
new ColorPalette();
🎭 第五步:美化界面样式
在media/palette.css中添加样式:
/**
* 图片色卡样式文件
* 作者:CarrieXin
*/
body {
font-family: var(--vscode-font-family);
color: var(--vscode-foreground);
background-color: var(--vscode-editor-background);
margin: 0;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
}
.controls {
display: flex;
gap: 15px;
margin-bottom: 20px;
align-items: center;
}
.control-group {
display: flex;
flex-direction: column;
gap: 5px;
}
.color-item {
height: 80px;
border-radius: 8px;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease;
display: flex;
align-items: flex-end;
position: relative;
overflow: hidden;
}
...
🔧 第六步:调试和测试
本地调试
- 按
F5(macfn + F5)启动调试模式 - 在新窗口中测试插件功能
- 在资源管理器中右键图片文件
- 选择"生成图片色卡"
常见问题解决
问题:版本兼容性
测试时发现报错
ERROR @types/vscode ^1.103.0 greater than engines.vscode ^1.74.0.
Either upgrade engines.vscode or use an older @types/vscode version
确保`package.json`中的版本配置一致:
这是因为engines.vscode 版本为 ^1.74.0,@types/vscode 版本为 ^1.103.0
,两者版本不匹配导致打包失败,将版本号统一即可
{
"engines": {
"vscode": "^1.74.0"
},
"devDependencies": {
"@types/vscode": "^1.74.0"
}
}
📦 第七步:打包和发布
安装打包工具
npm install -g vsce
打包插件
# 编译项目
npm run compile
# 打包成.vsix文件
vsce package
本地安装测试
方式一:命令安装
# 安装打包好的插件
code --install-extension image-color-palette-0.0.1.vsix
方式二:上传 vsix 文件

image.png
发布插件
将生成的插件vsix文件上传到插件广场

image.png

image.png
至此一款 VSCode 插件就开发完成并上传到拓展商店,可以提供给其他人使用了🎉🎉🎉
插件效果如图

image.png