Add local background removal and mask tools
This commit is contained in:
86
src/tools/background-remover/index.ts
Normal file
86
src/tools/background-remover/index.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { lazy } from "react";
|
||||
import type { PlimiPlugin } from "../../core/plugins/plugin-types";
|
||||
import { runBackgroundRemover } from "./run";
|
||||
import {
|
||||
estimateUncachedDownloadBytes,
|
||||
type BackgroundRemoverOptions,
|
||||
} from "./remove";
|
||||
import BgWorker from "./worker?worker";
|
||||
|
||||
export type { BackgroundRemoverOptions } from "./remove";
|
||||
|
||||
const BackgroundRemoverUi = lazy(() => import("./BackgroundRemoverUi"));
|
||||
|
||||
function formatMb(bytes: number): string {
|
||||
return `${(bytes / 1024 / 1024).toFixed(0)} MB`;
|
||||
}
|
||||
|
||||
export const backgroundRemoverPlugin: PlimiPlugin<BackgroundRemoverOptions> = {
|
||||
manifest: {
|
||||
id: "background-remover",
|
||||
name: "Background Remover",
|
||||
description:
|
||||
"Remove the background from any image with AI, entirely in your browser. Your photo is never uploaded.",
|
||||
category: "image",
|
||||
version: "1.0.0",
|
||||
tags: ["image", "background", "remove", "ai", "transparent", "cutout"],
|
||||
input: {
|
||||
type: "files",
|
||||
accept: ["image/png", "image/jpeg", "image/webp"],
|
||||
multiple: false,
|
||||
},
|
||||
output: { type: "files" },
|
||||
offlineReady: true,
|
||||
},
|
||||
|
||||
optionsSchema: {
|
||||
fields: [
|
||||
{
|
||||
type: "select",
|
||||
key: "quality",
|
||||
label: "Quality",
|
||||
defaultValue: "small",
|
||||
options: [
|
||||
{ label: "Smallest download (quantized)", value: "small" },
|
||||
{ label: "Balanced (FP16)", value: "medium" },
|
||||
{ label: "Best quality (FP32)", value: "large" },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "boolean",
|
||||
key: "useGpu",
|
||||
label: "Use GPU (WebGPU) when available",
|
||||
defaultValue: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
capabilities: {
|
||||
cancelable: false,
|
||||
worker: true,
|
||||
persistentWorker: true,
|
||||
wasm: true,
|
||||
customUi: true,
|
||||
preview: true,
|
||||
},
|
||||
|
||||
getRunWarning: async (_input, options) => {
|
||||
const bytes = await estimateUncachedDownloadBytes(options, self.location.origin);
|
||||
if (bytes <= 0) return null;
|
||||
const label =
|
||||
options.quality === "small"
|
||||
? "Smallest download"
|
||||
: options.quality === "medium"
|
||||
? "Balanced"
|
||||
: "Best quality";
|
||||
return (
|
||||
`Running the “${label}” model needs a one-time download of about ` +
|
||||
`${formatMb(bytes)} to your device. It is cached afterwards, so future ` +
|
||||
`runs are instant and fully offline. Continue?`
|
||||
);
|
||||
},
|
||||
|
||||
run: runBackgroundRemover,
|
||||
worker: () => new BgWorker(),
|
||||
customUi: BackgroundRemoverUi,
|
||||
};
|
||||
Reference in New Issue
Block a user