ExportX Figma插件使用说明[中文]
快速开始
我们的插件支持 「设计模式」和「Dev模式」, 查看下面视频,快速了解插件使用方式~
导出格式支持与压缩率
我们支持同时压缩多种格式和倍率的图片,但是规则限制在5条以内,图片格式支持:
格式 | 支持 | 节省空间 |
---|---|---|
AVIF | 是 | ≈92% |
WEBP | 是 | ≈88% |
JPG | 是 | ≈85% |
PNG | 是 | ≈68% |
SVG | 是 | ≈8% |
ico | 🚧 开发中 | - |
压缩效果根据统计得出,实际效果可能有所不同,此表格将持续更新。
历史记录
插件压缩的图片我们会在您的电脑上永久的存储起来,直到您清空缓存或者清除历史纪录。
受限于客户端存储限制,我们仅保存15条历史纪录。
免费图床服务
ExportX为您提供了能够快速上传的免费图床,服务建立在Cloudflare的免费CDN上,我们保证不删除您的图片。方便您0配置即可获得上传体验。
打开插件右上角的开关,即可使用我们的免费图床服务。
此时,点击”ExportX”按钮,一键完成压缩、上传操作。在历史记录中,点击复制按钮,即可获得图片链接。
使用我们的免费图床需要遵守我们的相关协议。
当然,我们更推荐您使用自定义上传服务。
自定义上传服务
如果您有自己的对象存储服务,您可以通过替换成自己的上传接口。 首先,点击左上角的[设置],在上传设置中,选择”自定义”方式。
上传接口规范
开启自定义上传后,图片会通过POST
请求上传到您的接口。接口需要遵守以下规范:
Request内容
Header: 您可以通过自定义header来传递token等信息。
Content-Type: multipart/form-data;
Body: 插件通过form-data的方式上传文件,下面的参数是插件提供的,同时,您可以通过自定义Body来传递额外的信息。
参数名 | 类型 | 说明 |
---|---|---|
file | File | 二进制文件 |
fileName | String | 文件名,如image92.avif |
format | String | 图片格式,如png |
figmaName | String | Figma用户名,用户可以在Figma中修改,不是唯一的,但具有可读性。 |
figmaId | String | Figma用户ID ,19位的数字,参考Figma User |
xid | String | 组合字段,格式为figmaName@figmaId |
Response内容
您需要给插件返回一个json对象,包含图片的url,url用于复制到剪贴板,如果没有返回url,复制按钮将不可用。
{
"url": "https://dev.cdn.abfree.com/images/6FjJoXmt34ox0Fu1.png"
}
Cloudflare R2+Worker
示例代码,此处使用hono来演示
import { Hono } from "hono";
type Bindings = {
MY_BUCKET: R2Bucket;
CDN_URL: string;
};
const app = new Hono<{
Bindings: Bindings;
}>();
app.post("/upload", async (c) => {
const key = genFileKey();
const formData = await c.req.parseBody();
const file = formData["file"];
if (file instanceof File) {
const fileBuffer = await file.arrayBuffer();
const fullName = file.name;
const ext = fullName.split(".").pop();
const path = `images/${key}.${ext}`;
let contentType = file.type;
if (contentType === "image/svg") {
contentType = "image/svg+xml";
}
console.log(file.type);
await c.env.MY_BUCKET.put(path, fileBuffer, {
httpMetadata: {
contentType: contentType,
contentDisposition: `inline`,
},
});
return c.json({
url: `${c.env.CDN_URL}/${path}`,
});
} else {
return c.text("Invalid file", 400);
}
});
Amazon S3 或兼容S3
大多数对象存储都兼容S3协议,比如
- AWS S3
- Cloudflare R2
- Google Cloud Storage
- 阿里云OSS
- 腾讯云COS
示例代码
// api.ts
import { Hono } from "hono";
import { uploadToS3 } from "./s3";
type Bindings = {
CDN_URL: string;
};
const app = new Hono<{
Bindings: Bindings;
}>();
app.post("/uploadS3", async (c) => {
const key = genFileKey();
const formData = await c.req.parseBody();
const file = formData["file"];
if (file instanceof File) {
const fileBuffer = await file.arrayBuffer();
const fullName = file.name;
const ext = fullName.split(".").pop();
const path = `images/${key}.${ext}`;
let contentType = file.type;
if (contentType === "image/svg") {
contentType = "image/svg+xml";
}
const uint8Array = new Uint8Array(fileBuffer);
await uploadToS3(c, {
file: uint8Array,
contentType,
key: key,
});
return c.json({
url: `${c.env.CDN_URL}/${path}`,
});
} else {
return c.text("Invalid file", 400);
}
});
// s3.ts
import { S3 } from "@aws-sdk/client-s3";
import { Context } from "hono";
let s3Client: S3;
interface UploadParams {
file: Uint8Array;
contentType: string;
key: string;
}
export async function uploadToS3(c: Context, params: UploadParams) {
const client = getClient(c);
await client.putObject({
Body: params.file,
Bucket: c.env.S3_BUCKET,
Key: params.key,
ContentType: params.contentType,
});
}
function getClient(c: Context) {
if (s3Client) return s3Client;
const { S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_ENDPOINT, S3_REGION } =
c.env;
s3Client = new S3({
credentials: {
accessKeyId: S3_ACCESS_KEY_ID,
secretAccessKey: S3_SECRET_ACCESS_KEY,
},
endpoint: S3_ENDPOINT,
region: S3_REGION,
});
return s3Client;
}
QA
上传是如何发起的
为了保护您图片的隐私性,上传行为是由前端发起,因此您可能需要处理跨域问题。
如何避免服务不被滥用
一般情况下,您填入的上传服务接口是公网可访问的,如果接口泄露,这样可能会导致匿名访问甚至滥用。因此,我们建议您使用xid
+secret
白名单的方式来限制访问。
什么是xid?
xid
是figmaId和figmaName的组合字段,格式为figmaName@figmaId
。它包含在上传的body当中,您可以在接口中校验这个字段是否在白名单中。
- figmaName,是Figma登录信息中用户的名字,用户可以在Figma中修改,不是唯一的,但具有可读性。
- figmaId,19位的数字,是Figma登录信息中用户的唯一标识.
具体可以参阅[Figma User]
xid
难以被伪造,已经足够安全,但是如果您需要更高的安全性,我们建议您增加一个secret
字段。
什么是secret?
secret
是您自己设置的密码,您可以自己生成并颁发给用户,用户在使用插件时需要在Body中填入这个密码。
当然这只是一种建议,具体的安全策略需要根据您的实际情况来制定。
如何排查上传错误
如果您在浏览器中使用Figma,可以在开发者工具中查看Network或Console面板,查看上传的请求和返回。
如果您使用的Figma客户端,您可以按下面提示打开控制台获取错误信息。
如何获取我的xid
在插件首页,点击右上角的用户按钮,您可以看到您的xid。