@@ -35,6 +35,7 @@ public partial class ImageToImage : UserControl, INavigatable, INotifyPropertyCh
3535 private bool _isGenerating ;
3636 private int _selectedTabIndex ;
3737 private bool _hasInputResult ;
38+ private bool _isControlsEnabled ;
3839 private ImageInput _inputImage ;
3940 private ImageResult _resultImage ;
4041 private ModelOptionsModel _selectedModel ;
@@ -64,6 +65,7 @@ public ImageToImage()
6465 BatchOptions = new BatchOptionsModel ( ) ;
6566 ImageResults = new ObservableCollection < ImageResult > ( ) ;
6667 ProgressMax = SchedulerOptions . InferenceSteps ;
68+ IsControlsEnabled = true ;
6769 InitializeComponent ( ) ;
6870 }
6971
@@ -153,6 +155,12 @@ public int SelectedTabIndex
153155 set { _selectedTabIndex = value ; NotifyPropertyChanged ( ) ; }
154156 }
155157
158+ public bool IsControlsEnabled
159+ {
160+ get { return _isControlsEnabled ; }
161+ set { _isControlsEnabled = value ; NotifyPropertyChanged ( ) ; }
162+ }
163+
156164
157165 /// <summary>
158166 /// Called on Navigate
@@ -192,18 +200,9 @@ private async Task Generate()
192200 {
193201 HasResult = false ;
194202 IsGenerating = true ;
203+ IsControlsEnabled = false ;
195204 ResultImage = null ;
196- var promptOptions = new PromptOptions
197- {
198- Prompt = PromptOptions . Prompt ,
199- NegativePrompt = PromptOptions . NegativePrompt ,
200- DiffuserType = DiffuserType . ImageToImage ,
201- InputImage = new StableDiffusion . Models . InputImage
202- {
203- ImageBytes = InputImage . Image . GetImageBytes ( )
204- }
205- } ;
206-
205+ var promptOptions = GetPromptOptions ( PromptOptions , InputImage ) ;
207206 var batchOptions = BatchOptions . ToBatchOptions ( ) ;
208207 var schedulerOptions = SchedulerOptions . ToSchedulerOptions ( ) ;
209208
@@ -214,8 +213,11 @@ private async Task Generate()
214213 if ( resultImage != null )
215214 {
216215 ResultImage = resultImage ;
217- ImageResults . Add ( resultImage ) ;
218216 HasResult = true ;
217+ if ( BatchOptions . IsAutomationEnabled && BatchOptions . DisableHistory )
218+ continue ;
219+
220+ ImageResults . Add ( resultImage ) ;
219221 }
220222 }
221223 }
@@ -241,7 +243,7 @@ private async Task Generate()
241243 private bool CanExecuteGenerate ( )
242244 {
243245 return ! IsGenerating
244- && ! string . IsNullOrEmpty ( PromptOptions . Prompt )
246+ && ! string . IsNullOrEmpty ( PromptOptions . Prompt )
245247 && HasInputResult ;
246248 }
247249
@@ -298,6 +300,7 @@ private bool CanExecuteClearHistory()
298300 private void Reset ( )
299301 {
300302 IsGenerating = false ;
303+ IsControlsEnabled = true ;
301304 ProgressValue = 0 ;
302305 }
303306
@@ -312,6 +315,9 @@ private void Reset()
312315 /// <returns></returns>
313316 private async IAsyncEnumerable < ImageResult > ExecuteStableDiffusion ( IModelOptions modelOptions , PromptOptions promptOptions , SchedulerOptions schedulerOptions , BatchOptions batchOptions )
314317 {
318+ if ( ! IsExecuteOptionsValid ( PromptOptions ) )
319+ yield break ;
320+
315321 _cancelationTokenSource = new CancellationTokenSource ( ) ;
316322 if ( ! BatchOptions . IsAutomationEnabled )
317323 {
@@ -321,15 +327,61 @@ private async IAsyncEnumerable<ImageResult> ExecuteStableDiffusion(IModelOptions
321327 }
322328 else
323329 {
324- var timestamp = Stopwatch . GetTimestamp ( ) ;
325- await foreach ( var batchResult in _stableDiffusionService . GenerateBatchAsync ( modelOptions , promptOptions , schedulerOptions , batchOptions , ProgressBatchCallback ( ) , _cancelationTokenSource . Token ) )
330+ if ( _batchOptions . BatchType != BatchOptionType . Realtime )
331+ {
332+ var timestamp = Stopwatch . GetTimestamp ( ) ;
333+ await foreach ( var batchResult in _stableDiffusionService . GenerateBatchAsync ( modelOptions , promptOptions , schedulerOptions , batchOptions , ProgressBatchCallback ( ) , _cancelationTokenSource . Token ) )
334+ {
335+ yield return await GenerateResultAsync ( batchResult . ImageResult . ToImageBytes ( ) , promptOptions , batchResult . SchedulerOptions , timestamp ) ;
336+ timestamp = Stopwatch . GetTimestamp ( ) ;
337+ }
338+ yield break ;
339+ }
340+
341+ // Realtime Diffusion
342+ IsControlsEnabled = true ;
343+ while ( ! _cancelationTokenSource . IsCancellationRequested )
326344 {
327- yield return await GenerateResultAsync ( batchResult . ImageResult . ToImageBytes ( ) , promptOptions , batchResult . SchedulerOptions , timestamp ) ;
328- timestamp = Stopwatch . GetTimestamp ( ) ;
345+ var refreshTimestamp = Stopwatch . GetTimestamp ( ) ;
346+ if ( SchedulerOptions . HasChanged || PromptOptions . HasChanged )
347+ {
348+ PromptOptions . HasChanged = false ;
349+ SchedulerOptions . HasChanged = false ;
350+ var realtimePromptOptions = GetPromptOptions ( PromptOptions , InputImage ) ;
351+ var realtimeSchedulerOptions = SchedulerOptions . ToSchedulerOptions ( ) ;
352+
353+ var timestamp = Stopwatch . GetTimestamp ( ) ;
354+ var result = await _stableDiffusionService . GenerateAsBytesAsync ( modelOptions , realtimePromptOptions , realtimeSchedulerOptions , RealtimeProgressCallback ( ) , _cancelationTokenSource . Token ) ;
355+ yield return await GenerateResultAsync ( result , promptOptions , schedulerOptions , timestamp ) ;
356+ }
357+ await Utils . RefreshDelay ( refreshTimestamp , BatchOptions . RealtimeRefreshRate , _cancelationTokenSource . Token ) ;
329358 }
330359 }
331360 }
332361
362+ private bool IsExecuteOptionsValid ( PromptOptionsModel prompt )
363+ {
364+ if ( string . IsNullOrEmpty ( prompt . Prompt ) )
365+ return false ;
366+
367+ return true ;
368+ }
369+
370+
371+ private PromptOptions GetPromptOptions ( PromptOptionsModel promptOptionsModel , ImageInput imageInput )
372+ {
373+ return new PromptOptions
374+ {
375+ Prompt = promptOptionsModel . Prompt ,
376+ NegativePrompt = promptOptionsModel . NegativePrompt ,
377+ DiffuserType = DiffuserType . ImageToImage ,
378+ InputImage = new StableDiffusion . Models . InputImage
379+ {
380+ ImageBytes = imageInput . Image . GetImageBytes ( )
381+ }
382+ } ;
383+ }
384+
333385
334386 /// <summary>
335387 /// Generates the result.
@@ -404,6 +456,24 @@ private Action<int, int, int, int> ProgressBatchCallback()
404456 } ;
405457 }
406458
459+ private Action < int , int > RealtimeProgressCallback ( )
460+ {
461+ return ( value , maximum ) =>
462+ {
463+ App . UIInvoke ( ( ) =>
464+ {
465+ if ( _cancelationTokenSource . IsCancellationRequested )
466+ return ;
467+
468+ if ( BatchOptions . StepValue != value )
469+ BatchOptions . StepValue = value ;
470+ if ( BatchOptions . StepsValue != maximum )
471+ BatchOptions . StepsValue = maximum ;
472+ } ) ;
473+ } ;
474+ }
475+
476+
407477 #region INotifyPropertyChanged
408478 public event PropertyChangedEventHandler PropertyChanged ;
409479 public void NotifyPropertyChanged ( [ CallerMemberName ] string property = "" )
0 commit comments