Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make a basic implement for webui plugin #24

Merged
merged 26 commits into from May 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9e4da7a
Make a basic implement for webui plugin
jtydhr88 May 19, 2023
8ba2ab7
add model and sampler select
jtydhr88 May 19, 2023
057c68f
add a setting for webui host url
jtydhr88 May 20, 2023
05ee9fb
bug fix
jtydhr88 May 20, 2023
a737c19
add init image(img2img) support
jtydhr88 May 20, 2023
47f769b
add cfg scale
jtydhr88 May 20, 2023
e7673fe
add mask/inpaint/outpaint support
jtydhr88 May 20, 2023
5af86c8
store settings and check webui status
jtydhr88 May 21, 2023
7d73a79
add load existing images by extension on webui
jtydhr88 May 22, 2023
f87e365
add upscale support
jtydhr88 May 22, 2023
59fe854
add a setting for history image count, and improve generated date
jtydhr88 May 22, 2023
53ec45f
Update README
cruhl May 22, 2023
2f4c155
Merge branch 'main' of https://github.com/Stability-AI/StableStudio i…
cruhl May 22, 2023
4d93006
read seed for existing images
jtydhr88 May 23, 2023
8478fc6
Update README
cruhl May 23, 2023
e9b649b
Merge branch 'webui-plugin' of https://github.com/jtydhr88/StableStud…
cruhl May 23, 2023
85c3ff7
Update thanks link
cruhl May 23, 2023
e7d1fb7
More readme tweaks
cruhl May 23, 2023
6ac5f78
Remove images
cruhl May 23, 2023
de681e7
refactor
KAJdev May 23, 2023
5cc7eaf
fix comment
KAJdev May 23, 2023
981036a
fix to get generated images
jtydhr88 May 24, 2023
562685e
read image info from api
jtydhr88 May 24, 2023
8951fd7
Wording tweaks
cruhl May 24, 2023
5beb7fc
List first-party plugins
cruhl May 24, 2023
3dc0e66
Merge branch 'main' into webui-plugin
cruhl May 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 8 additions & 10 deletions README.md
Expand Up @@ -4,18 +4,16 @@
<img src="./misc/GenerateScreenshot.png" style="width: 400px; max-width: 600px; flex-grow: 1;" />
<img src="./misc/EditScreenshot.png" style="width: 400px; max-width: 600px; flex-grow: 1;" />

<h3>
<span>👋 Welcome to StableStudio, the open-source version of <a href="https://dreamstudio.ai" target="_blank">DreamStudio</a></span>
<h3>👋 Welcome to StableStudio, the open-source version of <a href="https://dreamstudio.ai" target="_blank">DreamStudio</a>!</h3>

**🗺 Contents – [🚀 Quick Start](#quick-start) · [ℹ️ About](#about) · [🙋 FAQ](#faq) · [🧑‍💻 Contributing](#contributing)**

**📚 Documentation – [🎨 UI](./packages/stablestudio-ui/README.md) · [🔌 Plugins](./packages/stablestudio-plugin/README.md) · <a href="https://platform.stability.ai" target="_blank">⚡️ platform.stability.ai</a>**

**🔗 Links – <a href="https://discord.com/channels/1002292111942635562/1108055793674227782" target="_blank">🎮 Discord</a> · <a href="https://dreamstudio.ai" target="_blank">🌈 DreamStudio</a> · <a href="https://github.com/Stability-AI/StableStudio/issues">🛟 Bugs & Support</a> · <a href="https://github.com/Stability-AI/StableStudio/discussions">💬 Discussion</a>**

<br />
<br />
<span>[ <a href="./packages/stablestudio-ui/README.md">🎨 UI README</a> ]</span>
<span>[ <a href="./packages/stablestudio-plugin/README.md" href="./packages/stablestudio-ui/README.md">🔌 Plugins README</a> ]</span>
<span>[ <a href="https://discord.gg/stablediffusion" target="_blank">🎮 Discord</a> ]</span>
<span>[ <a href="https://github.com/Stability-AI/StableStudio/issues">🛟 Bugs & Support</a> ]</span>
<span>[ <a href="https://github.com/Stability-AI/StableStudio/discussions">💬 Discussion</a> ]</span>
</h3>

<hr />

</div>

Expand Down
Binary file added misc/Electric1111.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -15,6 +15,7 @@
"stablestudio-plugin-webui": "yarn workspace @stability/stablestudio-plugin-webui",
"stablestudio-ui": "yarn workspace @stability/stablestudio-ui",
"dev:use-example-plugin": "cross-env VITE_USE_EXAMPLE_PLUGIN=true yarn dev",
"dev:use-webui-plugin": "cross-env VITE_USE_WEBUI_PLUGIN=true yarn dev",
"dev": "yarn workspaces foreach --all --interlaced --verbose --parallel --jobs unlimited run dev",
"build": "yarn workspaces foreach --all --interlaced --verbose --jobs unlimited run build",
"clean": "yarn workspaces foreach --all --interlaced --verbose --parallel --jobs unlimited run clean && rimraf node_modules"
Expand Down
68 changes: 67 additions & 1 deletion packages/stablestudio-plugin-webui/README.md
@@ -1 +1,67 @@
Soon™️
<div align="center">

# 🔌 [`stable-diffusion-webui`](https://github.com/AUTOMATIC1111/stable-diffusion-webui) Plugin

**🗺 Contents – [ℹ️ About](#about) · [⚙️ Usage](#usage) · [⭐️ Features](#features)**

**[⬆️ Top-Level README](../../README.md)**

![Electric1111](../../misc/Electric1111.png)

</div>

# <a id="about" href="#about">ℹ️ About</a>

This plugin enables StableStudio to run using [`stable-diffusion-webui`](https://github.com/AUTOMATIC1111/stable-diffusion-webui), which means you can generate images entirely on your own machine!

Thanks goes to [Terry Jia](https://github.com/jtydhr88) for the original work on this plugin.

# <a id="usage" href="#usage">⚙️ Usage</a>

1. First, you'll need to configure your local installation of `stable-diffusion-webui` to run without the UI and with CORS enabled.

**Windows**

Edit the command line arguments within `webui-user.bat`:

```
set COMMANDLINE_ARGS=--nowebui --cors-allow-origins=http://localhost:3000
```

**Mac**

Edit the command line arguments within `webui-macos-env.sh`:

```
export COMMANDLINE_ARGS="--nowebui --cors-allow-origins=http://localhost:3000"
```

2. Start `stable-diffusion-webui` and look for `INFO: Uvicorn running on http://127.0.0.1:7861`.

You can make sure everything is running correctly by checking to see if [`http://127.0.0.1:7861/docs`](http://127.0.0.1:7861/docs) displays API documentation.

3. Within your installation of StableStudio, run `yarn dev:use-webui-plugin`.

_**That's it!**_ 🎉 You should now be able to generate images using your local machine.

## <a id="image-history" href="#image-history">💾 Image History</a>

To persist your image history, you'll need to install the [`sd-webui-StableStudio`](https://github.com/jtydhr88/sd-webui-StableStudio) extension for `stable-diffusion-webui`.

> 🛑 Be wary installing third-party extensions for `stable-diffusion-webui`, it's always a good idea to check before running untrusted code.

# <a id="features" href="#features">⭐️ Features</a>

Missing something? Please [let us know](https://github.com/Stability-AI/StableStudio/issues/new/choose)!

- [x] Text-to-image
- [x] Image-to-image
- [x] Basic features (prompt, negative prompt, steps, batch size, image size)
- [x] Model selection
- [x] Sampler selection
- [x] Masking, in-painting, and out-painting
- [x] Settings storage
- [x] Accurate plugin status
- [x] [Loading existing images]("#image-history)
- [x] Upscaling
- [ ] Lora support
184 changes: 184 additions & 0 deletions packages/stablestudio-plugin-webui/src/Utilities.ts
@@ -0,0 +1,184 @@
import { StableDiffusionInput } from "@stability/stablestudio-plugin";

export function base64ToBlob(base64: string, contentType = ""): Promise<Blob> {
return fetch(`data:${contentType};base64,${base64}`).then((res) =>
res.blob()
);
}

export function blobToBase64(blob: Blob): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();

reader.onloadend = () => resolve(reader.result as string);
reader.onerror = reject;

reader.readAsDataURL(blob);
});
}

export async function fetchOptions(baseUrl: string | undefined) {
const optionsResponse = await fetch(`${baseUrl}/sdapi/v1/options`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});

return await optionsResponse.json();
}

export async function setOptions(baseUrl: string | undefined, options: any) {
const optionsResponse = await fetch(`${baseUrl}/sdapi/v1/options`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(options),
});

return await optionsResponse.json();
}

export async function getImageInfo(
baseUrl: string | undefined,
base64image: any
) {
const imageInfoResponse = await fetch(`${baseUrl}/sdapi/v1/png-info`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ image: base64image }),
});

const imageInfoJson = await imageInfoResponse.json();

const info = imageInfoJson.info.split("\n");

const data: any = {};

if (info.length === 0) {
return data;
}

data.prompt = info[0];

let detailIndex = 1;

if (info.length === 3) {
data.nagtivePrompt = info[1].split(":")[1].trim();

detailIndex = 2;
}

const details = info[detailIndex].split(",");

details.map((detail: any) => {
const detailInfo = detail.trim().split(":");

data[detailInfo[0]] = detailInfo[1].trim();
});

return data;
}

export async function testForHistoryPlugin(webuiHostUrl: string) {
// timeout after 1 second
const finished = Promise.race([
fetch(`${webuiHostUrl}/StableStudio/get-generated-images`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
limit: 1,
}),
}),
new Promise((_, reject) =>
setTimeout(() => reject(new Error("Request timed out")), 1000)
),
]);

try {
await finished;
return (finished as any).ok;
} catch (error) {
return false;
}
}

export async function constructPayload(
options: {
input?: StableDiffusionInput | undefined;
count?: number | undefined;
},
isUpscale = false,
upscaler: string | undefined
) {
const { sampler, prompts, initialImage, maskImage, width, height, steps } =
options?.input ?? {};

// Construct payload
const data: any = {
seed: options?.input?.seed === 0 ? -1 : options?.input?.seed,
cfgScale: options?.input?.cfgScale ?? 7,
};

if (isUpscale) {
/*
Upscaling values
*/

data.upscaling_resize_w = width ?? 512;
data.upscaling_resize_h = height ?? 512;
data.upscaler_1 = upscaler;
} else {
/*
regular image generation values
*/

data.width = width ?? 512;
data.height = height ?? 512;

data.sampler_name = sampler?.name ?? "";
data.sampler_index = sampler?.name ?? "";

data.prompt =
prompts?.find((p) => (p.text && (p.weight ?? 0) > 0) ?? 0 > 0)?.text ??
"";
data.negative_prompt =
prompts?.find((p) => (p.text && (p.weight ?? 0) < 0) ?? 0 < 0)?.text ??
"";

data.steps = steps ?? 20;
data.batch_size = options?.count;
data.save_images = true;
}

if (initialImage?.weight && !isUpscale) {
data.denoising_strength = 1 - initialImage.weight;
}

if (initialImage?.blob) {
const initImgB64 = await blobToBase64(initialImage?.blob);

if (isUpscale) {
data.image = initImgB64.split(",")[1];
} else {
data.init_images = [initImgB64.split(",")[1]];
}
}

if (maskImage?.blob) {
const maskImgB64 = await blobToBase64(maskImage?.blob);

data.mask = maskImgB64.split(",")[1];

data.inpainting_mask_invert = 1; // Mask mode
data.inpainting_fill = 1; // Masked content
data.inpaint_full_res = false; // Inpaint area
}

return data;
}