Commit Graph
137 Commits
Author SHA1 Message Date
ausboss 4a60f58ff0 Merge branch 'fix/see-through-paint' into rc/2026-09-30 2026-09-30 00:33:42 -05:00
ausboss 3bbe3d4911 Stitch Inpaint: catch a gray fill handed back darker, and fit the advice
The unpainted check counted a flat block only within 10/255 of the fill.
Krea 2 can hand a 128 gray fill back as a flat 114 to 118, so a picture
with gray corners got no word. Flat blocks now count within 20/255, and so
does the picture's own flat area that is taken off first, so a flat wall
continued flat still stays quiet.

The message told still pictures that dark footage paints better when
brightened first. That line is now only for videos, in plainer words.

The warning had no changelog entry yet; it has one now.
2026-09-30 00:19:46 -05:00
ausboss ff7b751544 Merge branch 'rc/2026-09-30' into fix/see-through-paint 2026-09-29 23:53:53 -05:00
ausboss a416420bfa Crop + Rotate + Pad: paint see-through parts, add prompt_image
A see-through part of a picture - a cutout's missing background, an oval
photo's corners, a hole - kept its stored colour blended over the fill.
That colour is often black or the old background, so the model got a
dark or light ring round the picture and Stitch Inpaint pasted part of it
back. A pixel less than 90% as solid as the picture's most solid pixel is
now empty, like a corner a turn leaves: filled with the fill colour,
marked in the mask, new area for both seams. Kept pixels are fully solid
in their own colour.

A new last output, prompt_image, is the image with see-through parts on
white instead of the fill, for the node that writes the prompt: shown the
gray fill, a prompt writer describes a gray backdrop and the model keeps
it. original shows see-through parts on white instead of black.

A picture at least 90% solid everywhere goes through exactly as before;
the new tests hold every output and both seams to the old transform.
2026-09-29 23:18:19 -05:00
ausboss 36a0b5ca6a Merge branch 'fix/mask-refine-fill-limit' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
2026-09-29 22:39:30 -05:00
ausboss 11b5a6d56a Mask Refine: Max hole size, so fill holes leaves the part you kept
Paint everything except a person or a pet, turn on fill holes, and it
filled the unpainted subject too, so the part meant to stay was repainted.
The new optional max_hole_size input (a percent of the picture, 0 to 100)
sets the biggest hole fill holes fills. The default, 0, fills every hole
exactly as before, so saved workflows and API prompts run the same; at 2
the gaps a quick brush leaves still fill and a subject left unpainted
stays. Areas touching the picture's edge are never holes, as before.

- Hole sizes come from scipy's labels, the same 4-connected holes its
  fill finds; the torch fallback labels the same 8-connected holes as its
  own fill. Each picture in a batch is measured on its own, after expand.
- The card gets a Max hole size row with a % unit, dimmed while Fill holes
  is off, and a resetUnknown fallback of 0 for 2.x saves that hold the
  card's empty value in its slot.
- Tests: a hole above the limit stays, holes up to it fill, 0 matches the
  old fill, edge-touching areas never fill, the torch fallback agrees,
  batches, and older saves opening with 0.
- Node API snapshot, help page and changelog.
2026-09-29 22:38:36 -05:00
ausboss ae2af9db47 Merge branch 'fix/clip-node-ux' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
#	example_workflows/LTX 2.3 Video Outpaint (AusBoss).json
#	js/input_preview/index.js
2026-09-29 22:16:33 -05:00
ausboss f7c6803f2b Crop + Rotate + Pad: the new notes no longer make the node taller
A node sized for the old face could grow into the node below once the new
notes showed. Now:
- The size line names the lit ratio where it acted ("pad to 16:9
  1821x1024") instead of adding a line, and "already 9:16: pick another
  ratio or turn it" sits on the same line when it fits.
- The Even out, To start and Full clip buttons fit their lines.
- "= the whole clip. Shorten it to move IN" fits beside the Length on the
  example workflow's node.
- A new picture only ever shrinks the picture area to its shape; it never
  grows the node.
2026-09-29 22:04:25 -05:00
ausboss 3044e16eb3 Merge branch 'fix/clear-errors' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
2026-09-29 21:50:27 -05:00
ausboss 5a6317467a Say "No mask painted" when a picture reaches a mask node without one
Core Load Image hands out a 64x64 mask of zeros when the picture has no
mask painted on it, and picking a new picture after painting one gives
the same. Krea 2 Inpaint Masked then stopped inside Crop For Inpaint with
"Mask size (64, 64) does not match image size (1216, 832)".

Crop For Inpaint, Color Match and Mask Refine (with its picture wired)
now say "No mask painted: right-click your picture, choose Open in
MaskEditor, paint the area, then click Save." A mask made for another
picture names both sizes. LaMa Inpaint used to resize the blank stand-in
and hand the picture back unchanged; it says the same now. An empty mask
of the picture's own size still runs as before: Crop For Inpaint takes
the whole picture and stitches it back untouched.
2026-09-29 21:43:20 -05:00
ausboss cb05fcc9b7 Docs and changelog for the clearer canvas and preview controls
The help pages, the README and the changelog use the new names (Round
canvas to, Frames for, Server file, the Resize switch) and describe the
always-scrubbing timeline and its grip, the padlock rules, the "already
this shape" note, the resize warning and Even out, the preview switch
bringing its picture back, Compare's labels and the Workflow Note's Use it.
2026-09-29 21:43:07 -05:00
ausboss d27040e20b Merge branch 'fix/krea2-outpaint-paint' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
2026-09-29 21:41:09 -05:00
ausboss f9bca9927a Merge branch 'fix/stitch-seam-turned' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
2026-09-29 21:41:09 -05:00
ausboss 67c620589e Merge branch 'feat/workflow-note-fit' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
2026-09-29 21:41:09 -05:00
ausboss faf0462067 Stitch Inpaint: say when an outpaint comes back unpainted
An outpaint whose new area still shows the plain fill color used to come
back as a finished-looking picture with bars. Stitch Inpaint now measures
how much of the new area is still flat at the fill color, beyond what the
source picture itself has, and when a quarter of it (or half of any
checked frame) is left, says so in the console and in a toast.

The check lives in its own helper, works for images and video and for any
fill color, and stays quiet on dark scenes that are painted.
2026-09-29 17:51:01 -05:00
ausboss d14b717090 Stitch Inpaint: Tone match works with Seam set to blend in
Blend in kept the model's colour as painted, so a model that paints
lighter, darker or warmer left the new area off-tone. Classic's Tone
match is no answer on turned pictures: it reads the grey rim a turn
leaves on the picture's edge as drift, and its flat offset lifts the
black of a dark new area.

With Tone match on, blend in now compares the model's version of the
strip it redrew with the picture at the same pixels (tone layers over
the same clean picture pixels, clipped highlights left out), fits the
drift as curves over brightness with a pinned and a free part, checks
the fit on held-out tiles, adds a local gain along the edge only when
that holds out too, and takes the result back off the model's picture
before the blend. Blacks stay black; nothing changes when the check
fails, the model kept the colours, or there is no feather to read. A
clip is measured once.

Classic is unchanged (its pins), and blend in at Tone match 0 is pinned
to the 2.4.0 stitch. The card no longer dims Tone match under blend in.
2026-09-29 16:56:12 -05:00
ausboss 9abead5a78 Krea 2 Encode: show AnyPaint the new area in the picture's own colour
A dark or colourful picture padded with the #808080 gray came back from
Krea 2 AnyPaint with the gray still there: a gray frame around the picture,
or gray corners on a turned one. AnyPaint was trained with the new area of
its reference filled with the median colour of the picture, so a gray patch
next to a dark photo reads to it as part of the scene and it paints it back.
It did the same with every Krea 2 model file tried.

Krea 2 Encode gets an optional mask input, appended last. When it is wired,
the new area of the reference (mask above 0.5) is refilled with the median
colour of the rest before it reaches the VAE and the vision tower. The
canvas the rest of the graph uses keeps its gray. Without the link nothing
changes.
2026-09-29 16:50:26 -05:00
ausboss 58b450d21e Crop + Rotate + Pad: the editor's Multiple and Steps are Align and Step
The node face calls canvas_multiple Align and resolution_steps Step; the
full-screen editor called the same two settings Multiple and Steps.
2026-09-29 16:41:58 -05:00
ausboss 8ed782de89 Crop + Rotate + Pad: one state per ratio button, a padlock, a real turn
Prototype of the ratio row, for review. A chip used to stay lit after a
drag changed the shape (16:9 lit on a 1889x1280 canvas), a second tap on
it locked and a third cleared every pad, the portrait/landscape button
threw away hand edits, a locked diamond dragged inward did not move, and
Crop | Pad looked like two more ratio chips.

- A chip is lit only while the canvas (crop plus padding, before Align)
  has its ratio; the pick (properties.ausboss_fit_aspect) is dropped when
  a gesture leaves it, so a new clip is only fitted to a shape the canvas
  still has. Without a picture a tapped ratio waits for the first one.
- Tap = reach the ratio (pad, or crop with Fit on crop), tap the lit one =
  back to the whole picture. No other chip state.
- Holding the shape is a padlock button (ausboss_aspect_lock): drags keep
  the lit ratio, or the custom one, from the moment you grab a handle.
- The orientation button turns the shape: pad mode pads the current crop
  to the turned ratio, crop mode turns the crop box about its centre.
  Nothing to turn (no picture, untouched, square): only the labels turn.
- Custom / Source caption, and the real ratio on the size line.
- Fit is a segmented pill; switching it re-reaches a lit ratio.
- Rotation keeps a lit ratio (and a held custom one).
- Dragging the picture where the crop spans the source slides it inside
  its padding (slidePadding).
- The editor's Ratio list applies at once; Hold shape is the padlock.

Saved properties and widget values keep their names and meaning; an old
locked chip opens with the padlock on. Pure rules in transform_geometry
(canvasSize, aspectMatches, turnAspect, turnedCrop, padAround,
slidePadding, ratioLabel, isUntouched) with node:test coverage.
2026-09-29 16:22:27 -05:00
ausboss 2bc842bd41 Workflow Note: grow to fit its text in the classic canvas
A note saved a few pixels shorter than its content showed a scrollbar and
hid its last row. The LTX 2.3 Video Outpaint note in the smaller example
layout (440 x 810) was 6 px short, so its links sat behind the scrollbar.
The classic canvas keeps a node's saved height; Nodes 2.0 already sized
the note to its content.

The note now measures its card's natural height at the node's width and
grows the node to fit when a workflow opens, after an edit, after the file
check, and when the node's width changes, since the text rewraps. It never
shrinks the node. The load fit runs before ComfyUI snapshots the opened
workflow, so a note that grows on load does not mark the workflow modified.
A corner drag stops at the fit, as it does in Nodes 2.0: holdNodeMinHeight
lifts the node's computeSize height to the measured floor. A card less
than half a pixel short is left alone, because Chrome rounds that away and
draws no scrollbar. Nodes 2.0 is untouched.
2026-09-29 10:50:57 -05:00
ausboss f34169a132 Update the Krea 2 Outpaint example
Replace it with the version that pads with Image Crop + Rotate + Pad,
with its sample picture and a new thumbnail. Point the README's Load
Image + Pad section at Klein 9B Outpaint, and update the example table,
the outpaint caption, the Krea 2 Outpaint Model Patch help page and the
CHANGELOG. Raise the Registry archive budget to 18 MB.
2026-09-29 02:06:08 -05:00
ausboss 3a315e2924 Trim the example workflows
Keep Krea 2 Outpaint, Klein 9B Outpaint, LTX 2.3 Video Outpaint,
Qwen Image 2.1 Edit + Realign and Simple Video Watermark Remover, and add
Krea 2 Inpaint Masked and Krea 2 Rotate + Outpaint with their sample
pictures. Remove the other sixteen examples and the sample picture only
they used.

Update the README example table and links, the Realign to Source help
page, a test comment, the CHANGELOG and the pyproject description, and
raise the Registry archive budget to 13 MB.
2026-09-29 01:52:07 -05:00
ausboss 20afbf2536 Stitch Inpaint: move Seam into a gear menu
The card keeps its old look and height. Seam has no row and no socket
now: a small gear in the card's top-right corner opens a menu with the
two choices, each with one plain line. With blend in on, Tone match and
Fix edge halo stay in place but dim and stop taking input, with a hover
hint, and a "blend in" chip beside the gear shows the mode.

The seam widget is a socketless combo, so the frontend makes no input
slot for it in either renderer; a stale unlinked slot from an earlier
save is dropped on load. The backend input is unchanged.

The widget card gains two generic options for this: rows can be muted
by the current values, and a card can carry small corner tools that
every row's control keeps clear of. A gear-menu choice can list one
line per option.
2026-09-29 00:19:01 -05:00
ausboss 89e82f6d70 Stitch Inpaint: say when blend in helps
Blend in suits turned pictures and outpaints with Tone match off. With straight padding and Tone match on, classic usually looks as good, because the model's slight tone drift stays as painted in blend in. The help page also limits the unchanged round-trip promise to the classic seam.
2026-09-29 00:19:01 -05:00
ausboss 65784651d1 Stitch Inpaint: add a Seam option for outpaint canvases
Seam is a new optional choice, appended after color_match. "classic"
is the default and the old stitch, bit for bit. "blend in" hands the
model's picture over to the source by depth into the picture: colour
and tone change over slowly, fine detail changes over in a short ramp
where the two line up, the new area keeps the model's pixels, and the
deep picture keeps its own. There is no global tone shift, so
color_match and fix_edge_halo do not apply and the card hides them.

The depth map comes from the generated-area mask of a Crop + Rotate
+ Pad stitcher, or from the source rectangle of a Load Image + Pad
stitcher, with sides flush with the frame left out. It is computed
once per stitcher and shared by every frame, with scipy when present
and an exact torch fallback otherwise. Crop For Inpaint stitchers
keep the classic stitch. With blend in, blend_mask is the hand-over
weight.

An older workflow can carry the card's empty value in the slot Seam
now takes; the card resets it to classic on load and the node accepts
it as classic. Classic output is pinned against the previous code for
Load Image + Pad, Crop + Rotate + Pad, Crop For Inpaint and clip
stitchers.
2026-09-29 00:19:01 -05:00
ausboss 59a12aee6c Merge remote-tracking branch 'origin/main' into feat/resolution-width-lora-names
# Conflicts:
#	CHANGELOG.md
2026-09-28 19:39:31 -05:00
ausboss daee65c719 Merge remote-tracking branch 'origin/main' into fix/crop-inside-picture
# Conflicts:
#	CHANGELOG.md
2026-09-28 19:01:47 -05:00
ausboss 45b27dd94a Latent Size (was Resolution Master): resizable; LoRA Loader long-name choice
Resolution Master is renamed Latent Size: the old name belongs to another
node pack. The node id AUSBOSS_NODES_Resolution is unchanged, so saved
workflows and API graphs load and run as before. Workflows only store a
title that differs from the default, so they pick up the new name; a saved
title that starts with "Resolution Master 🆎" gets the new name in its
place on load. The example, its thumbnail and the README image follow.

- Latent Size can be resized: wider stretches the chips, fields and size
  picks, and taller gives the stage the room. It opens at 340 x 531 as
  before and goes down to 320, where the size row tightens so W, H and MP
  stay whole.
- LoRA Loader: gear -> Long names, end (the default, as before) or middle,
  which keeps the checkpoint number at the end of a name in view. The
  picker opens wide enough for long names and shortens the folder first.
- The frontend adds 104 px to a DOM panel's minWidth before using it as
  the node's floor (LGraphNode.computeSize), so a node that opened
  narrower jumped wider the moment its corner was touched: the LoRA Loader
  could not go under 424. fillNodeHeight gains exactMinWidth, which
  measures that padding and takes it back off, and holdVueNodeMinWidth
  lends the floor to Nodes 2.0, whose corner drag reads the node's inline
  min-width instead. Both nodes use them; the other panels keep their old
  floors for now.
- README: the workflow-tools image shows Latent Size alone; the Seed card
  is gone.
2026-09-28 18:34:03 -05:00
ausboss b8c9dff562 Crop For Inpaint: keep the crop inside the picture (on by default)
When the grown context box was bigger than the picture on an axis (a wide
or tall mask, or a small picture), fit_rect centred it and the overflow was
replicate-padded: the sampler got stretched copies of the edge pixels, and
a megapixel target spent its budget on them. On a 1184x2112 portrait with
the coat painted, only 42% of the canvas was the picture and the new part
was drawn at 0.52x.

New optional input keep_inside (card row "Stay in picture", on by
default) clamps the box to the picture on the overflowing axis before it
is fitted, so the crop holds only real pixels (0.80x on that portrait).
The helper keeps the old padding by default for existing callers; off on
the node is the old crop. Appended as the last optional input, so saved
workflows keep their values; ones whose box ran past the picture now
render a little differently.
2026-09-28 18:07:50 -05:00
ausboss 750f1e4860 Krea 2 Outpaint docs: drop the inpaint claim, fix Crop For Inpaint
The example's Workflow Note and the Krea 2 Outpaint Model Patch help page
said you could paint over part of the picture with the mask editor and pad
at the same time. Load Image + Pad drops the picture's alpha, its mask
covers only the new padding, and it hides the core preview the mask editor
opens from, so that never worked. Both now say the workflow only extends
the picture outward.

The help page also said a Crop For Inpaint stitcher places the reference
over the full frame. On source rectangle it falls back to where the crop
sat in the full picture, so the page now says to use whole canvas with one.
2026-09-28 15:20:15 -05:00
ausboss 62fcc88262 Edit + Realign example writes its own prompt; plain docs; LoRA Loader in every example
- Qwen Image 2.1 Edit + Realign: type a short edit and Qwen3-VL 8B, the
  text encoder the edit already loads, writes the full instruction. The
  consistency LoRA sits in a LoRA Loader row, switched off.
- LTX 2.3 Video Outpaint: the distilled LoRA and the outpaint IC-LoRA load
  in one LoRA Loader instead of two core loaders. The workflow checks now
  refuse core LoRA loaders in examples.
- Realign to Source: description, tooltips and help page rewritten in
  plain words, with the technical detail at the end of the help page.
- Settings menus: in a short window the rows no longer squeeze together
  and overlap; the menu scrolls instead.
- AGENTS.md: text people read starts with the plainest version.
2026-09-27 21:00:26 -05:00
ausboss ff59d55f41 Realign to Source: margins, whole-pixel cuts and big zooms
An edit made at the picture's own size loses whatever the model pushed
past the canvas edge, so realigning it left an empty strip on 13 of 16
held-out edits. Realign to Source now takes an optional stitcher: given
Load Image + Pad's stitcher for the padded canvas the edit was made on,
it measures inside the picture's area only and returns just that area,
so what the model drew into the margin fills the edges.

- A drift within half a pixel of a whole-pixel shift is cut straight
  out of the edit with no resampling; an edit that already lines up
  comes back untouched.
- The coarse pass also tries the edit at 0.86x-1.28x, so a large zoom
  is found; models often reframe a padded canvas by zooming in to fill
  it, and that zoom does not count toward Max zoom.
- The report says whether the frame was cut out or warped and names the
  margin each side needed when an edit ran out of picture.

Load Image + Pad gains a mirror fill, which models read as more of the
scene: over 16 edits it provoked a reframe on 2, against 7 for edge
pixels and 5 for flat gray. The Qwen Image 2.1 Edit + Realign example
now edits on a 64 px mirror margin with the stitcher wired.
2026-09-27 19:48:55 -05:00
ausboss 9e33f62ba6 Merge main into feat/load-image-pad-input 2026-09-27 18:04:30 -05:00
ausboss fdbc674d8a Add Realign to Source (experimental): undo an edit's zoom and shift
Qwen Image 2.1 draws broad edits (watercolor, anime, oil) a few percent
taller than the source, up to about 12%, differently for every seed, and
snapping sizes does not change it. Realign to Source measures that zoom
and shift against the source and warps the edit back onto the source's
frame, at the source's size. empty_mask marks the strip the model pushed
out of view; report gives the measured zoom, shift and worst corner, or
why a frame was left as it is. The display name carries EXPERIMENTAL.

Promoted from the lab node. The measurement is unchanged (the same
matrices on 166 real Qwen 2.1 renders). The warp now samples the edit
with its edge pixels extended for every fill, so the gray and source
fills no longer draw a dark line beside the strip.

New example: Qwen Image 2.1 Edit + Realign, the Qwen 2.1 Edit graph with
the realign step after decode, its report, and before and after compares.
2026-09-27 13:53:59 -05:00
ausboss f32917321e Load Image + Pad: pad a wired image
An optional source_image socket pads an image from another node instead
of the chosen file, so a step before the pad (flattening a transparent
picture onto white, say) no longer has to be saved and loaded back.

- The wire wins over the file; validation skips the file check while it
  is connected and runs core's link-type check itself, since asking for
  input_types turns core's off for the node.
- A wired run hands the canvas a small temp preview (one file per node,
  overwritten each run) and the true source size, so the stage draws the
  last image it padded; before the first run it shows an outline.
- Card rows gain linkedBy, so the Source row dims while a wire replaces it.
- Appended and optional with no widget: saved workflows and API prompts
  load unchanged. Node API snapshot refreshed.
2026-09-27 01:45:51 -05:00
ausboss 33cdf80a60 Merge fix/pad-leftover-sliver: Load Image + Pad adds no strip along an unpadded edge
Resolved: CHANGELOG keeps every bullet, with this bundle's transform and
stitch bullets grouped after main's.
2026-09-26 22:26:38 -05:00
ausboss ed548503f7 Merge fix/rotated-seam-color-match: tone match reads only picture pixels on rotated canvases
Resolved: CHANGELOG keeps both bullets. The feather branch's
perfect-continuation test left rotated-and-padded out because of this
bug; with both fixes in, it covers that layout too.
2026-09-26 22:26:13 -05:00
ausboss c4a0e011e6 Merge fix/crop-rotate-pad: rotation keeps the crop, size readout, Clip Length (B2 dropped)
Resolved:
- node_image_crop_rotate_pad.py: optional inputs are the four resize
  inputs, then stitch_blend, then stitch_grow; node_api.json regenerated
  with test_node_api.py --update (no breaking change against main).
- test_transform_outputs.py: the optional-inputs test expects the stitch
  inputs after the resize ones.
- transform_editor.mjs: the Inpaint & Stitch section and its status line
  serve the image node too (feather branch) beside the size-chain status
  (this branch); the Cancel code is #73's, line for line.
- LTX example note and the Clip help page carry both branches' wording.
- CHANGELOG keeps every bullet.
2026-09-26 22:25:48 -05:00
ausboss d3e2c4bdd5 Merge feat/editor-cancel-discard (#73): the editor Cancel change fix/crop-rotate-pad was built on
# Conflicts:
#	js/shared/transform_editor.mjs
2026-09-26 22:22:59 -05:00
ausboss 996403d511 Merge fix/transform-mask-only-feather: feather softens the mask only 2026-09-26 22:22:41 -05:00
ausboss 415ca971ad Load Image + Pad: no strip along an edge nobody padded
Rounding the canvas to Multiple put the leftover on the right and bottom
whatever was padded, so the published Krea 2 Outpaint workflow (top and
bottom padded, Multiple 16, Budget 1.6) grew a 6 px grey strip down the
photo's right edge. Krea painted it flat, the feather opened the photo
beside it, and Stitch's colour match read it as a seam.

The leftover now joins a padded side (the far one when both are). An
axis nobody padded is scaled onto the multiple when a Budget is set (one
uniform scale) and trimmed evenly without one; the node's canvas shows
the trim as -N px. The JS preview (pad_canvas.mjs / pad_panel.mjs)
mirrors the Python plan to the pixel. Crop + Rotate + Pad keeps its old
rule for now.
2026-09-26 22:22:14 -05:00
ausboss 0025994528 Stitch tone match: read only picture pixels on rotated canvases
On a Crop + Rotate + Pad canvas that was rotated and padded (a canvas
multiple's few pixels count), the source rectangle is the crop, which
holds the rotation's empty corners. color_match read their fill as
picture and shifted the whole fill toward it: up to 33 dE on a flat
test, 57 with a resize. The transform stitcher now carries its
generated-area mask; the seam reading skips void pixels (2 px clear of
them), and a line with no picture takes the band's global offset.

Load Image + Pad and Crop For Inpaint carry no mask and stitch exactly
as before; a pin test holds Load Image + Pad's colour-matched bands to
their old values.
2026-09-26 22:22:14 -05:00
ausboss a3a9be54bf Crop + Rotate + Pad: rotation keeps the crop, size readout, Clip Length
- Rotating keeps the crop's size over the same part of the picture from
  the knob, slider, number box and Reset rotation (cropForRotation).
- A readout under the picture names every step that sets the output size
  (crop -> pad -> align -> resize) and warns when the resize Step
  stretches the picture or Align pads fill ahead of a resize; ticking
  Resize shows Megapixels and Step on the face.
- Locked-aspect crops use integer maths (_ratio_box / ratioBox), so the
  size shown equals the run.
- Image Crop + Rotate + Pad's four resize inputs are optional, so API
  prompts saved before them validate again.
- Video Crop + Rotate + Pad -> Clip: one Length switch replaces the Fixed
  frames and Limit boxes; OUT sits on the last output frame; a connected
  fixed_frames / frame_load_cap takes over the length.
- The stitcher pastes the unfaded canvas when feather > 0
  (transform_pil_layers / keep_unfaded). Superseded by mask-only feather
  and dropped in the next commit.

Carries a copy of the editor Cancel / discard-prompt change from
feat/editor-cancel-discard (#73), which this work was built on.
2026-09-26 22:21:16 -05:00
ausboss 1ef1b31918 Crop + Rotate + Pad: feather softens the mask only; image stitch inputs
The image and video transform nodes faded the picture into the fill
colour across the feather ramp. Outpaint models read that ramp as
content (the Qwen 2.1 outpaint LoRA painted a darker band along a tilted
edge, LTX's IC-LoRA left feathered bars unpainted), and the stitcher
kept the faded pixels, so Stitch's colour match measured its drift
against them and pulled the fill toward grey (d(ab) 18.5 at feather 24 on
a straight pad, 2.6 now). Feather now shapes only the mask and the stitch
blend built from it; the picture keeps a hard edge against the fill, so a
feathered canvas is the feather-0 canvas pixel for pixel.

Image Crop + Rotate + Pad gains the clip node's optional stitch_blend
(32) and stitch_grow (0) inputs, and its editor shows the same Inpaint &
Stitch section with Show blend. The editor's live fade overlay goes with
the fade.
2026-09-26 22:21:09 -05:00
ausboss 2d8273ebb6 Merge remote-tracking branch 'origin/main' into feat/editor-cancel-discard
# Conflicts:
#	CHANGELOG.md
2026-09-26 22:14:12 -05:00
ausboss 70b3135df3 Merge pull request #72 from ausboss/feat/save-image-preview
Save Image: preview switch and Embed workflow: no | yes
2026-09-26 22:08:37 -05:00
ausboss 235225000c Editors: Cancel with a discard-changes prompt
The Crop + Rotate + Pad editor gains Cancel beside Save & close; Escape
now cancels. Changed edits ask first (shared js/shared/discard_prompt.mjs)
and Discard restores the node to its state when the editor opened. The
Workflow Note editor asks before Cancel, Escape or a backdrop click drops
edits, and a JSON edit carried back to the form no longer outlives Cancel.
2026-09-26 17:59:48 -05:00
ausboss 2a5df316cb Save Image: preview switch and Embed workflow no | yes
Save Image joins the shared input_preview panel with the PREVIEW switch,
backed by a new optional preview input (display only: the file is saved
and listed in the queue either way). The embed row reads
Embed workflow: no | yes.
2026-09-26 17:58:25 -05:00
ausboss f616661eff Show A on the left and B on the right in Compare 2026-09-26 17:58:11 -05:00
ausboss 9e086969bf Improve Compare slider snapping and explicit A/B preview locks 2026-09-26 17:51:07 -05:00