大家都知道,就在10天前,吾皇开放了“不是什么神奇的东西”之图片编辑的接口,能够定向编辑遮罩区域的内容(虽然被群佬们测出了一堆Bug
ChatGPT Plus金牌销售之Chat2API图片生成+编辑
实际使用的时候,如果希望编辑的区域并不规整(例如选择背景、天空等等),手涂遮罩就显得效率很低了,所以向各位坛佬介绍一种自动选区的办法。
segment anything 是meta开源的用于图像分割的模型,一经推出火爆了整个CV领域,而借助于 transformers.js 我们可以在浏览器端使用它。恰好有大佬开发了一款浏览器插件 magic copy 可以帮助我们很方便的在浏览器里完成图像分割的任务。
但是这个项目用于吾皇的接口上存在一些问题:
- 最终下载提供的是选区图片,而非完整的图片保留选区部分
- 选区是原始图片的截图,非黑色遮罩
- 背景是透明,非白色
我们可以通过fork项目并修改其中关键的代码来满足我们的需求:
修改以下文件 src/components/hooks/useImageEditor.ts
中的部分代码为:
React.useEffect(() => {
if (!bitmap || !traced) {
return;
}
const offscreen = new OffscreenCanvas(bitmap.width, bitmap.height);
const offscreenCtx = offscreen.getContext("2d", {
willReadFrequently: true,
});
if (!offscreenCtx) return;
for (const path of traced) {
offscreenCtx.fill(new Path2D(path));
}
offscreenCtx.fillStyle = "rgba(0, 0, 0, 1)";
offscreenCtx.globalCompositeOperation = "source-in";
offscreenCtx.drawImage(bitmap, 0, 0);
const trimmed = trim(
offscreenCtx.getImageData(0, 0, bitmap.width, bitmap.height)
);
if (trimmed == null) {
setRenderedImage(null);
} else {
const [tx, ty, tw, th] = trimmed;
const copy = new OffscreenCanvas(bitmap.width, bitmap.height);
const copyCtx = copy.getContext("2d");
if (copyCtx === null) {
throw new Error("Could not get context");
}
copyCtx.fillStyle = "white";
copyCtx.fillRect(0, 0, bitmap.width, bitmap.height);
var imageData = offscreenCtx.getImageData(tx, ty, tw, th);
for (let i = 0; i < imageData.data.length; i += 4) {
if (imageData.data[i + 3] !== 0) {
imageData.data[i] = 0;
imageData.data[i + 1] = 0;
imageData.data[i + 2] = 0;
} else {
imageData.data[i] = 255;
imageData.data[i + 1] = 255;
imageData.data[i + 2] = 255;
imageData.data[i + 3] = 255;
}
}
copyCtx.putImageData(imageData, tx, ty);
copy.convertToBlob({ type: "image/png" }).then(setRenderedImage);
}
}, [bitmap, traced]);
当然,我已经编译好了 chrome 版本的供大家使用(在仓库release中找),解压缩后在扩展程序打开开发者模式,加载即可。
看下效果:
点击感兴趣的区域:
Preview 查看:
Download 下载:
ONLY AT LINUX DO