diff --git a/examples/cli/main.cpp b/examples/cli/main.cpp index 1cc7a7af4..eea756fd9 100644 --- a/examples/cli/main.cpp +++ b/examples/cli/main.cpp @@ -80,7 +80,7 @@ struct SDCliParams { &metadata_format}, {"", "--preview-path", - "path to write preview image to (default: ./preview.png). Multi-frame previews support .avi, .webm, and animated .webp", + "path to write preview image to (default: ./preview.png). For image generation, the filename can have %03d placeholder for sequential numbering. Multi-frame previews support .avi, .webm, and animated .webp", 0, &preview_path}, {"", @@ -372,27 +372,6 @@ bool load_images_from_dir(const std::string dir, return true; } -void step_callback(int step, int frame_count, sd_image_t* image, bool is_noisy, void* data) { - (void)step; - (void)is_noisy; - SDCliParams* cli_params = (SDCliParams*)data; - // is_noisy is set to true if the preview corresponds to noisy latents, false if it's denoised latents - // unused in this app, it will either be always noisy or always denoised here - if (frame_count == 1) { - if (!write_image_to_file(cli_params->preview_path, - image->data, - image->width, - image->height, - image->channel)) { - LOG_ERROR("save preview image to '%s' failed", cli_params->preview_path.c_str()); - } - } else { - if (create_video_from_sd_images(cli_params->preview_path.c_str(), image, frame_count, cli_params->preview_fps) != 0) { - LOG_ERROR("save preview video to '%s' failed", cli_params->preview_path.c_str()); - } - } -} - std::string format_frame_idx(std::string pattern, int frame_idx) { std::smatch match; std::string result = pattern; @@ -412,6 +391,32 @@ std::string format_frame_idx(std::string pattern, int frame_idx) { return result; } +int continuous_preview_counter = 0; + +void step_callback(int step, int frame_count, sd_image_t* image, bool is_noisy, void* data) { + (void)step; + (void)is_noisy; + SDCliParams* cli_params = (SDCliParams*)data; + // is_noisy is set to true if the preview corresponds to noisy latents, false if it's denoised latents + // unused in this app, it will either be always noisy or always denoised here + if (frame_count == 1) { + fs::path path = cli_params->preview_path; + std::string new_pathname = fs::path(path).remove_filename().string() + + format_frame_idx(path.filename().string(), ++continuous_preview_counter); + if (!write_image_to_file(new_pathname, + image->data, + image->width, + image->height, + image->channel)) { + LOG_ERROR("save preview image to '%s' failed", new_pathname.c_str()); + } + } else { + if (create_video_from_sd_images(cli_params->preview_path.c_str(), image, frame_count, cli_params->preview_fps) != 0) { + LOG_ERROR("save preview video to '%s' failed", cli_params->preview_path.c_str()); + } + } +} + static fs::path get_video_audio_sidecar_path(const SDCliParams& cli_params) { fs::path out_path = cli_params.output_path; fs::path base_path = out_path;