Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,8 @@ All fields except `prompt` are optional. Omitted fields use the loaded model's d
|-------|------|---------|-------------|
| `prompt` | `string` | *(required)* | Text prompt |
| `negative_prompt` | `string` | `""` | Negative prompt |
| `width` | `int` | model default | Output width in pixels |
| `height` | `int` | model default | Output height in pixels |
| `width` | `int` | model default | Output width in pixels (0..4096) |
| `height` | `int` | model default | Output height in pixels (0..4096) |
| `steps` | `int` | model default | Number of denoising steps |
| `guidance_scale` | `float` | model default | CFG scale (≤ 1.0 disables CFG) |
| `seed` | `int` | random | Random seed (`-1` for random) |
Expand Down
4 changes: 2 additions & 2 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ def test_upscalers_available_without_model():
def test_text2image_passes_pixel_upscaler(tmp_path):
runtime = _fake_runtime(tmp_path)
app = create_app(runtime)
req = Text2ImageRequest(prompt="a fox", pixel_upscaler="RealESRGAN_x4")
req = Text2ImageRequest(prompt="a fox", width=512, height=512, pixel_upscaler="RealESRGAN_x4")
res = _endpoint(app, "/text2image")(req)
assert res.status_code == 200
assert runtime._pipeline.last_request.pixel_upscaler == "RealESRGAN_x4"


def test_request_field_defaults_none():
req = Text2ImageRequest(prompt="x")
req = Text2ImageRequest(prompt="x", width=512, height=512)
assert req.pixel_upscaler is None
1 change: 1 addition & 0 deletions thenoise/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Text2ImageRequest(BaseModel):
negative_prompt: str = ""
width: Optional[int] = None
height: Optional[int] = None

steps: Optional[int] = None
guidance_scale: Optional[float] = None
seed: Optional[int] = None
Expand Down
9 changes: 9 additions & 0 deletions thenoise/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,21 @@
import logging
import os
import random
import sys

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


def run_generate(args) -> None:
_MAX_DIM = 4096
if args.width is not None and (args.width < 0 or args.width > _MAX_DIM):
print(f"error: width must be between 0 and {_MAX_DIM} (got {args.width}).", file=sys.stderr)
sys.exit(1)
if args.height is not None and (args.height < 0 or args.height > _MAX_DIM):
print(f"error: height must be between 0 and {_MAX_DIM} (got {args.height}).", file=sys.stderr)
sys.exit(1)

from .models.config import GenerateRequest
from .runtime import Settings, ModelPaths, Runtime
settings = Settings(device=args.device)
Expand Down
14 changes: 14 additions & 0 deletions thenoise/ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,13 @@ <h1>The<span class="dot">Noise</span></h1>
<div class="field">
<label for="width">Width</label>
<input type="number" id="width" placeholder="auto" value="1024">
<span class="hint">Max 4096</span>
</div>
<button class="swap" id="swap" title="Swap width and height" aria-label="Swap width and height">&#8646;</button>
<div class="field">
<label for="height">Height</label>
<input type="number" id="height" placeholder="auto" value="1024">
<span class="hint">Max 4096</span>
</div>
</div>

Expand Down Expand Up @@ -744,6 +746,18 @@ <h1>The<span class="dot">Noise</span></h1>
const samplerVal = $('sampler').value;
if (samplerVal) body.sampler = samplerVal;

const MAX_DIM = 4096;
for (const f of ['width', 'height']) {
const v = $(f).value === '' ? null : parseInt($(f).value, 10);
if (v !== null && (v < 0 || v > MAX_DIM)) {
btn.disabled = false;
clearInterval(timer);
overlay.classList.add('hidden');
alert(`error: ${f} must be between 0 and ${MAX_DIM} (got ${v}).`);
return;
}
}

try {
const res = await fetch('/text2image', {
method: 'POST',
Expand Down