Commit Graph
417 Commits
Author SHA1 Message Date
scraed 12c8035ffa Update the README news and index for v2.1.0 and refresh the Example_29 GIFs 2026-08-12 17:35:28 +08:00
scraed 9fe919558f Bump version to 2.1.0 and add the news entry v2.1.0 2026-08-12 17:29:34 +08:00
scraed 6948b2c766 Retire sampler hyperparameters, add MinStepFrac, and rework the video mask union
Retire Beta/Friction/EarlyStop/InnerThreshold/InnerPatience/MinStepFrac
from all sampler nodes: the widgets are gone, the values are fixed
constants, and old prompts still validate via hidden inputs. A value
sanitizer falls back to defaults on invalid widget values, and the
frontend migrates old workflows by key-based widgets_values mapping
(LAYOUTS table) instead of positional arrays, so kept parameters
(PromptMode, Inpainting_mode) survive on old workflows.

MinStepFrac defaults to 1.0: the inner step size is pinned and the
inner-step count ramps linearly with the remaining noise fraction.

Video mask union: resample nearest-exact first, then a slice-level
sliding max-pool (experimental order) so the mask follows the painted
region's motion through the video.

Update Example_29 with the new output and re-export the workflow JSON.
2026-08-12 17:24:03 +08:00
scraed 2771dd17d0 Keep the original GIF previews for Example_29
The animated previews (InPainted gif and the combined showcase gif) stay
as the original versions; only the mp4 outputs are updated with the fixed
run.
2026-08-12 02:11:21 +08:00
scraed f145728829 Fix MiniMax H3 on ComfyUI 0.31+ (FLOW_AV model type) and update Example_29
MiniMaxH3 became ModelType.FLOW_AV in ComfyUI 0.31 (bdcb886a: audio
carriage redesign); our IS_FLOW checks only matched ModelType.FLOW, so H3
silently fell into the VE schedule branch and sampled garbage (corrupted
video, clipped audio). Treat FLOW_AV as a flow type via a version-safe
getattr tuple.

Example_29: replace the output with the fixed run (InPainted mp4/gif +
combined showcase), and re-export example_workflows JSON from the new
output's embedded metadata. Bump version to 2.0.1.
2026-08-12 01:49:50 +08:00
scraed 1e146fa465 Add the VideoMaskEditor node description picture to the README 2026-08-10 10:46:12 +08:00
scraed c70c8f926b Use GIF previews for the MiniMax H3 example in the README
GitHub cannot render mp4 files inline, so the Example_29 media is also
published as GIFs (480px wide, 62 frames, ~3.9 MB) and the README links
(news block and MiniMax H3 section) point at the GIFs; the mp4 files stay
in the folder for download.
2.0.0
2026-08-09 23:45:11 +08:00
scraed 64fab713a5 Bump version to 2.0.0 2026-08-09 23:41:49 +08:00
scraed b95f51910c Announce MiniMax H3 support in the README news blocks
Add the MiniMax H3 video + audio inpainting announcement at the top of the
NEW blocks (with the mask-overlay visualization), pointing at the Example_29
media and the MiniMax H3 example section; the Updates list keeps the dated
entry.
2026-08-09 23:40:56 +08:00
scraed 6b04947fc6 Add a mask-visualization video to Example_29 and the README
Render the H3 example's actual interpolated mask sequence (from the 25
painted keyframes) as a red overlay on the input video, so the README can
show what was painted. The README's MiniMax H3 table now has three
columns (masked input / mask overlay / inpainted result), matching the
Wan example style.
2026-08-09 23:37:42 +08:00
scraed 8a491bfb94 Update the example InPainted drag-me PNGs with the new workflow outputs
The InPainted_Drag_Me_to_ComfyUI.png files of the converted examples are
replaced with the actual test-run outputs (which carry the workflow +
prompt tEXt chunks SaveImage embeds), so dragging them into ComfyUI loads
the new ImageEncode/ImageDecode workflows instead of the old encode chain.
Covers Examples 2, 7, 13, 14, 15, 20, 21, 23, 24, 25, 27, 28; verified
that every embedded workflow contains the new encode/decode nodes and has
no stale VAEEncode/SetLatentNoiseMask.
2026-08-09 23:26:28 +08:00
scraed 994c620cbd Document the MiniMax H3 AV pipeline in the README
Add feature bullets for the video+audio inpainting pipeline and the
masks-in-video export, plus a MiniMax H3 section under Video Examples
covering the editor -> AVEncode -> sampler -> AVDecode flow, the
Example_29 media, the mask export/import workflow, and links to the
MiniMax H3 Hugging Face repo and ComfyUI docs.
2026-08-09 23:15:12 +08:00
scraed d1ee798b60 Convert the remaining examples to ImageEncode/ImageDecode and finish the example set
- Qwen Image Edit upgraded to the 2509 model (qwen_image_edit_2509_fp8_e4m3fn)
  with TextEncodeQwenImageEditPlus multi-image conditioning; old 2508/2509
  pairs removed.
- New Z-Image base example (z_image_bf16, Example_25 input) using default
  LanPaint parameters (NumSteps 5, Lambda 5.0, StepSize 0.2, Friction 15);
  old turbo/base pairs removed.
- Renamed the converted examples to the *_EncodeDecode_Inpaint convention
  (fresh names force the workflow gallery to reload them) and generated
  preview jpgs from the test run outputs; superseded old pairs removed,
  Qwen_Image_Outpaint and wan2_2_T2I_Partial kept as distinct use cases.
- Fixed the Qwen Image example mask reference: Example_12's file has no
  alpha channel (it is an output example), so it now points at Example_13's
  masked input (7).
- Repositioned the ImageEncode/ImageDecode nodes next to the sampler in all
  converted workflows (the conversion agents had placed them far off-canvas).
- SD3.5 and HiDream examples removed on request.
- Example_29 now ships the H3 masked input video and the inpainted output
  video (InPainted_Drag_Me_to_ComfyUI.mp4).
2026-08-09 22:46:51 +08:00
scraed 59aa08dff0 Store masks inside exported videos and convert the example set to ImageEncode/ImageDecode
Mask-in-video (the masks now travel with the video file):
- New videometa module: write/read a JSON payload under the lanpaint-mask
  mp4 metadata tag via PyAV (stream copy, movflags=use_metadata_tags), so
  exporting produces a NEW file and the source is never modified.
- Two server routes: GET /lanpaint/video_mask_meta (read the payload back)
  and POST /lanpaint/export_mask_video (remux into input/<base>_masked.mp4).
- The mask editor exports the painted keyframes (base64 PNGs) + audio
  intervals into the video; loading a video with the tag auto-restores the
  masks (editor and node preview). A video without the tag clears the
  workflow's masks - the video is the source of truth. The export also
  offers a native save dialog (showSaveFilePicker) when available.
- The video widget upload now uses video_upload so MP4s are selectable in
  the file chooser (was image_upload).
- LanPaint_ImageEncode accepts 5D latents from video VAEs encoding a single
  image (e.g. the Hunyuan video VAE) - fixes the Hunyuan example.

Example set conversion (one example per supported model, new files, old
pairs removed after being superseded):
- New *ImageEncode/*EncodeDecode example workflows for SDXL, Flux.1,
  Flux.2 Dev, Flux2 Klein, SD3.5, Hunyuan, Ideogram4, Krea2, Qwen Edit,
  Qwen Image, Z-Image, Wan 2.2 and MiniMax H3 (AV), all using
  LanPaint_ImageEncode/ImageDecode instead of VAEEncode +
  SetLatentNoiseMask + VAEDecode + MaskBlend; every example references its
  own example folder's masked input (hash-verified); preview jpgs generated
  from the test runs; the H3 example ships its output mp4 as a preview.
- HiDream example removed on request; Example_29 added with the H3 masked
  input video.

Fixes along the way: normalize node input.link/output.links fields against
the links arrays in all converted workflows (the frontend renders
null-link nodes as disconnected); stale Inpainting_mode widget removed from
the Flux.2 sampler; Lambda defaults 5.0 (first-order scheme); torchaudio
resample test assertion relaxed (edge ringing); the videometa tests updated
to the final export signature.
2026-08-09 20:41:45 +08:00
scraed aa8f4e81ac Default LanPaint_Lambda to 5.0 for the first-order scheme
The second-order damped-oscillator scheme (position + velocity) is
disabled, and the active first-order overdamped scheme has no momentum,
so the 16.0 bidirectional guidance scale that suited the damped
oscillator over-drives the masked region. Lower the default Lambda to
5.0 in the basic KSampler's hardcoded value, the Advanced sampler's
INPUT_TYPES default and default argument, and the two custom samplers.
2026-08-09 01:26:01 +08:00
scraed f590861bd5 Add image encode/decode nodes and fix preview frame alignment
LanPaint_ImageEncode replaces VAEEncode + SetLatentNoiseMask (plus the
manual mask ImageScale): the mask is snapped to the latent's actual
spatial size (nearest-exact) so VAE padding can never mismatch again.
LanPaint_ImageDecode replaces VAEDecode + LanPaint_MaskBlend (plus the
dimension-alignment round trip): the decoded image is resized to the
original's exact dimensions, then merged with the original inside the
mask with a MaskBlend-style boundary. The image workflow collapses to
LoadImage -> ImageEncode -> sampler -> ImageDecode -> SaveImage.

merge_video_with_mask now accepts a single 2D mask (broadcast over the
frame batch) and keys the merge count off the image/frame tensors
instead of the mask, so a 1-frame mask no longer truncates a batch.

Three frontend fixes for frame-accurate previews in the video mask
editor: (1) measureVideoFps now spans about 80 percent of the duration
instead of 1 second - the short span had +-1 frame of counting
uncertainty, so the editor and node preview could round to different
integers (e.g. 29 vs 30) and their frame grids drifted by a frame;
(2) the preview overlay maps playback time to the frame index with
floor (the browser presents floor(t*fps), round() mislabeled by one
whenever the video paused mid-frame); (3) the editor's frameAt seek
gets a +1e-6 nudge so index/fps float dust cannot land on the previous
frame.

Also fix a save-race crash: if the editor dialog is closed while the
keyframe uploads are in flight, _flash queried this.el after it was
nulled and the handler reported Save failed even though the save
succeeded. _flash now tolerates a closed editor.
2026-08-09 00:27:11 +08:00
scraed 7514e28048 Use scipy EDT and share mask-morph math between frontend and backend
The video mask editor's backend interpolation was dominated by the
pure-Python Felzenszwalb-Huttenlocher EDT: 20 keyframes at 864x480 took
~168s. _edt_2d now uses scipy.ndimage.distance_transform_edt (exact same
distances, C speed, ~100x faster; the Python fallback stays for
environments without scipy) - the same scenario now takes ~1.6s.

The frontend preview and the backend no longer keep two separate morph
implementations that can drift: the pure math (EDT, SDF, shifts, sigmoid,
per-frame morph) moved to web/lanpaint_mask_math.js, used by the editor
extension and pinned against the backend by tests/parity_mask_math.mjs +
test_js_python_mask_math_parity, which feeds the same 8-bit keyframes to
both sides and asserts the soft masks match within 1e-4 and the 0.5 level
sets are pixel-identical. The preview also switched from the quantized
sigmoid LUT to the exact sigmoid the backend uses.

Fixed a caller-contract bug found while verifying: computeSDFEntry
expects a pure alpha array, but the extension passed raw RGBA bytes
(getImageData data), so soft strokes were read as fully solid and the
index alignment scrambled the SDF (visible as odd strips). The caller now
extracts the alpha channel, and the function throws when handed a
non-w*h array so the mistake fails loudly.
2026-08-08 19:09:11 +08:00
scraed e8e2d2ad1d Add AV encode/decode nodes for nested-latent video+audio inpainting
LanPaint_AVEncode replaces the workflow chain GetVideoComponents ->
VAEEncode -> SetLatentNoiseMask + MiniMaxAudioEncode -> SetLatentNoiseMask
-> Concat AV Latent: it decodes the video's frames and audio track from
the VIDEO reference, encodes both streams, and returns a nested AV latent
with the video and audio masks attached per-stream (no stock
SetLatentNoiseMask, which crashes on 1D masks).

LanPaint_AVDecode is the mirror: it decodes both streams, merges the
inpainted video into the original with MaskBlend-style boundary blending
(blend_overlap), merges the audio by mask intervals with a crossfade
(audio_crossfade, replicate-padded ramp so even kernels keep the exact
length), resamples the inpainted audio to the original rate, resizes the
VAE decode output to the original dimensions, and writes the result with
the original file's fps and bit depth via VideoFromComponents. A source
without an audio track falls back to the inpainted audio.

reshape_mask rework: video masks are aggregated per latent token with a
window-4 temporal max (union) followed by nearest-exact resample, and the
frames-at-batch [F,1,H,W] convention produced by SetLatentNoiseMask is
handled; audio masks [F], [F,1] or [1,1,F,1] are resampled to the audio
latent's token grid. The stock per-stream mask prep is routed through our
prepare_mask (video_inpainting for 5D targets) inside override_sample_function,
which now guards against nested entry. Audio encode is a pure encoder.

Also: editor node fps fallback for VideoFromFile.get_frame_rate, 5D decode
batch combine, audio channel-count match, and MaskBlend.gaussian_kernel
now shares the guarded kernel helper (fixing NaN at overlap=1).
2026-08-08 17:46:21 +08:00
scraed 7708715590 Add video mask editor with audio mask intervals
LanPaint_VideoMaskEditor now outputs a per-frame video mask and an audio
mask [F] (hard 0/1 at video frame rate) painted from time intervals in
the new hidden audio_mask widget. The frontend shows an audio waveform
strip under the video preview with red masked intervals and a playhead,
and the editor dialog supports drag-to-paint / click-to-clear intervals.

LanPaint_MiniMaxAudioEncode becomes a pure encoder (mask_start/mask_end
removed); the workflow attaches the editor's audio mask to the audio
latent with SetLatentNoiseMask and Concat AV Latent nests both per-stream
masks.

Video masks get the temporal union in reshape_mask: a latent token covers
~4 video frames and is all-or-nothing, so each token takes the window-4
max of its frames (nearest-exact) instead of trilinear averaging, which
could erase sparse temporal strokes. The stock per-stream mask prep is
routed through our prepare_mask (video_inpainting for 5D targets) and
handles the 1D [F] audio mask -> audio latent tokens case. Also handles
the VideoFromFile.get_frame_rate rename in newer ComfyUI.
2026-08-08 01:27:12 +08:00
scraed c9c79988f1 Update Krea2 example with latest output and workflow 2026-06-28 10:48:50 +08:00
scraed 9ce5bbb706 Bump version to 1.5.5 1.5.5 2026-06-27 23:43:05 +08:00
scraed 8b630eb6eb Update Flux2 Klein inpainting example with reference conditioning workflow 2026-06-27 23:42:01 +08:00
scraed 840c962fc9 Add Krea2 Turbo inpainting support with Example_28
- Add Krea2 banner, example section, and documentation to README
- Add new Example_28 with Krea2 LanPaint KSampler workflow
- Add workflow JSON and preview to example_workflows/
2026-06-27 17:45:09 +08:00
scraed 6a41445b8a Bump version to 1.5.4 2026-06-27 12:00:27 +08:00
scraed b71f8e59b4 Add Ideogram4 inpainting support with Example_27
- Add Ideogram4 banner, example section, and documentation to README
- Add new Example_27 with Ideogram4 LanPaint Custom Sampler Advanced workflow
- Add workflow JSON to example_workflows/
- Fix widgets_values in Example_23 and Example_24 InPainted images
1.5.4
2026-06-27 11:21:11 +08:00
scraed d696d48146 Add Anima support examples to README 2026-05-21 11:48:37 +08:00
scraed 6a0f424f28 Add Anima inpainting example and workflow updates
Add Anima (Example_26) inpainting/outpainting support: update README with Anima example and changelog entry, add three example images (Original, Masked, Inpainted). Modify example_workflows/Qwen_Image_Inpaint.json to restructure and extend the node graph (add VAE/encode/decode, mask/image scaling/conversion, mask blending, updated links and node ids) and bump frontendVersion/node metadata for compatibility. Update .gitignore to ignore Claude-related files. Replace the Example_13 inpainted image binary with an updated version.
2026-05-21 11:26:35 +08:00
scraed ba4bb687f1 Bump version to 1.5.3 for Info display improvement 1.5.3 2026-04-11 11:13:17 +08:00
scraed 3bd8a431ac Merge pull request #87 from octo-patch/fix/issue-61-info-widget-fixed-height
fix: prevent LanPaint_Info widget from expanding when node is resized
2026-04-11 11:12:06 +08:00
scraed 0ce81f2a49 Shrinked info and added a button instead 2026-04-11 11:10:01 +08:00
Octopus 9e7d0ee646 fix: remove multiline from LanPaint_Info widgets to prevent node resize expansion
When a LanPaint node is resized (e.g. to make the image preview bigger),
the LanPaint_Info multiline text box expanded along with it, wasting space.

Remove 'multiline: True' from the LanPaint_Info STRING input in all four
node types (LanPaint_KSampler, LanPaint_KSamplerAdvanced,
LanPaint_SamplerCustom, LanPaint_SamplerCustomAdvanced). The widget now
uses a fixed-height single-line display that does not grow when the node
is resized.

Fixes #61
2026-04-06 21:57:11 +08:00
scraed 75e606579c bump version 1.5.2 2026-03-26 17:10:41 +08:00
scraed 6440a7f433 unpack 2 bug fix for custom advanced node 2026-03-26 17:09:35 +08:00
scraed b3dc7e7551 bump version 2026-03-23 19:27:52 +08:00
scraed 2522687dd5 Klein workflow update 2026-03-23 19:26:45 +08:00
scraed f3ef9dedf9 update Klein workflow for resizing problem 2026-03-23 19:24:39 +08:00
scraed f53442c8d5 Revise README for v1.5.0 release notes
Updated README to include details about v1.5.0 bug fix and new features.
2026-03-03 11:46:56 +08:00
scraed 24051fb151 update README 1.5.0 2026-03-02 22:28:29 +08:00
scraed a76a5da0c5 bump version 2026-03-02 22:25:37 +08:00
scraed 21a6b155e8 fix the langevin output x has not been used issue 2026-03-02 14:16:32 +08:00
scraed 8bc20d5e00 Update README with additional resources and structure
Reorganized README content for clarity and added links to Diffusers
2026-02-16 01:03:30 +08:00
scraed 84b63adb11 replace flux example mask for bug fixing 2026-02-07 12:15:29 +08:00
scraed 725fb2ba37 Replace Klein example image 2026-02-07 11:56:03 +08:00
scraed 4f19674299 Update README.md 2026-02-04 14:40:08 +08:00
scraed 558084416d version 1.4.13 1.4.13 2026-02-02 23:49:35 +08:00
scraed a984dcb118 Fix flux klein example workflow 2026-02-02 23:48:33 +08:00
scraed 3f9193997a Update README.md 2026-02-02 20:36:55 +08:00
scraed 7372428114 Update README.md 2026-02-02 20:18:57 +08:00
scraed ac6eece747 Update Discord link in README.md 2026-02-02 20:15:45 +08:00
scraed 95b65ed1b1 Merge pull request #74 from godnight10061/fix/semantic-stop-tail
Add semantic inner-loop early stop mechanism
2026-01-30 11:44:51 +08:00