Skip to content

Commit

Permalink
Support Simple Video Editing
Browse files Browse the repository at this point in the history
  • Loading branch information
GetGet99 committed Jun 25, 2022
1 parent c1cadca commit f90350f
Show file tree
Hide file tree
Showing 6 changed files with 294 additions and 86 deletions.
110 changes: 104 additions & 6 deletions PhotoToys/Custom UI/SimpleUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
using Windows.ApplicationModel.DataTransfer;
using System.IO;
using Windows.Storage.Streams;
using Windows.Storage.Pickers;
using Windows.Storage;
using OpenCvSharp;
using Size = Windows.Foundation.Size;
using Rect = Windows.Foundation.Rect;

namespace PhotoToys;

Expand All @@ -18,6 +23,7 @@ public static void ImShow(this OpenCvSharp.Mat M, MatImage MatImage)
MatImage.Mat = M;
GC.Collect();
}
public static void ImShow(this Mat M, Action<Mat> Action) => Action.Invoke(M);
public static async Task ImShow(this OpenCvSharp.Mat M, string Title, XamlRoot XamlRoot)
{
await new ContentDialog
Expand Down Expand Up @@ -133,7 +139,7 @@ public static UIElement Generate(string PageName, string? PageDescription = null
VerticalScrollBarVisibility = ScrollBarVisibility.Auto
};
}
public static UIElement GenerateLIVE(string PageName, string? PageDescription = null, Action<MatImage>? OnExecute = null, params ParameterFromUI[] Parameters)
public static UIElement GenerateLIVE(string PageName, string? PageDescription = null, Action<Action<Mat>>? OnExecute = null, params ParameterFromUI[] Parameters)
{
var verticalstack = new FluentVerticalStack
{
Expand Down Expand Up @@ -168,11 +174,22 @@ public static UIElement GenerateLIVE(string PageName, string? PageDescription =
},
Children =
{
new TextBlock
new FluentVerticalStack
{
Text = "Result",
VerticalAlignment = VerticalAlignment.Center,
},
Children =
{
new TextBlock
{
Text = "Result",
VerticalAlignment = VerticalAlignment.Center,
},
new Button
{
Content = "Export Video",
Visibility = Visibility.Collapsed,
}.Assign(out var ExportVideoButton)
}
}.Assign(out var ExportVideoButtonContainer),
new MatImage
{
UIElement =
Expand All @@ -191,11 +208,92 @@ public static UIElement GenerateLIVE(string PageName, string? PageDescription =
{
if (Parameters.All(x => x.ResultReady))
{
OnExecute?.Invoke(MatImage);
OnExecute?.Invoke(x =>
{
MatImage.Mat = x;
GC.Collect();
});
}
verticalstack.InvalidateArrange();
};
if (p is ImageParameter imageParameter)
imageParameter.ParameterValueChanged += delegate
{
ExportVideoButton.Visibility =
(from pa in Parameters
where pa is ImageParameter impa && impa.IsVideoMode
select true).Count() == 1 ? Visibility.Visible : Visibility.Collapsed;
ExportVideoButtonContainer.InvalidateArrange();
};
}
ExportVideoButton.Click += async delegate
{
var para = (from pa in Parameters
where pa is ImageParameter impa && impa.IsVideoMode
select pa).FirstOrDefault(default(ParameterFromUI));
if (para is ImageParameter video && video.VideoCapture is VideoCapture vidcapture)
{
var picker = new FileSavePicker
{
SuggestedStartLocation = PickerLocationId.VideosLibrary
};

WinRT.Interop.InitializeWithWindow.Initialize(picker, App.CurrentWindowHandle);

picker.FileTypeChoices.Add("MP4", new string[] { ".mp4" });
picker.FileTypeChoices.Add("WMV", new string[] { ".wmv" });
picker.FileTypeChoices.Add("MKV", new string[] { ".mkv" });

var sf = await picker.PickSaveFileAsync();
if (sf != null)
{
var selectedframe = video.PosFrames;
var totalFrames = vidcapture.FrameCount;
var dialog = new ContentDialog
{
Content = new ProgressBar
{
//Value = 50,
}.Assign(out var progressRing),
XamlRoot = Result.XamlRoot,
};
async Task RunLoop()
{
await Task.Run(async delegate
{
using var writer = new VideoWriter(sf.Path, FourCC.MP4V, vidcapture.Fps,
new OpenCvSharp.Size(vidcapture.FrameWidth, vidcapture.FrameHeight)
);
for (int i = 0; i < totalFrames; i++)
{
video.PosFrames = i;
if (i % 10 == 0)
dialog.DispatcherQueue.TryEnqueue(delegate
{
progressRing.Value = (double)(i+1) / totalFrames * 100;
});
if (video.Result is null) break;
TaskCompletionSource<Mat> result = new();
OnExecute?.Invoke(x =>
{
result.SetResult(x);
GC.Collect();
});
writer.Write(await result.Task);
}
writer.Release();
});
};
_ = dialog.ShowAsync();

await RunLoop();
dialog.Hide();

video.PosFrames = selectedframe;

}
}
};

verticalstack.Children.Add(Result);
return new ScrollViewer
Expand Down
4 changes: 3 additions & 1 deletion PhotoToys/Parameters/CheckboxParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,16 @@ public CheckboxParameter(string Name, bool Default, bool? InvisibleResult = null
};
UI.RegisterPropertyChangedCallback(UIElement.VisibilityProperty, delegate
{
_Result = UI.Visibility == Visibility.Visible ? (CheckBox.IsChecked ?? false) : this.InvisibleResult;
ParameterValueChanged?.Invoke();
});
ParameterReadyChanged?.Invoke();
ParameterValueChanged?.Invoke();
}
public override bool ResultReady => true;
public bool _Result;
public new bool Result {
get => UI.Visibility == Visibility.Visible ? (CheckBox.IsChecked ?? false) : InvisibleResult;
get => _Result;
set => CheckBox.IsChecked = value;
}
protected override bool GetResult() => Result;
Expand Down
23 changes: 1 addition & 22 deletions PhotoToys/Parameters/DoubleSliderParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,6 @@ namespace PhotoToys.Parameters;

class DoubleSliderParameter : ParameterFromUI<double>
{
public class Converter : IValueConverter
{
double Min, Max;
Func<double, string> DisplayConverter;
public Converter(double Min, double Max, Func<double, string> DisplayConverter)
{
this.Min = Min;
this.Max = Max;
this.DisplayConverter = DisplayConverter;
}
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is not double Value) throw new ArgumentException();
return DisplayConverter.Invoke(Value + Min);
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
public override event Action? ParameterReadyChanged, ParameterValueChanged;
public DoubleSliderParameter(string Name, double Min, double Max, double StartingValue, double Step = 1, double SliderWidth = 300, Func<double, string>? DisplayConverter = null)
{
Expand Down Expand Up @@ -83,7 +62,7 @@ public DoubleSliderParameter(string Name, double Min, double Max, double Startin
Value = StartingValue - Min,
Width = SliderWidth,
Margin = new Thickness(0, 0, 10, 0),
ThumbToolTipValueConverter = new Converter(Min, Max, DisplayConverter)
ThumbToolTipValueConverter = new NewSlider.Converter(Min, Max, DisplayConverter)
}.Edit(x =>
{
x.ValueChanged += delegate
Expand Down
Loading

0 comments on commit f90350f

Please sign in to comment.