diff --git a/SpineViewer/Utils/BackgroundColorToForegroundColor.cs b/SpineViewer/Utils/BackgroundColorToForegroundColor.cs new file mode 100644 index 0000000..620da2c --- /dev/null +++ b/SpineViewer/Utils/BackgroundColorToForegroundColor.cs @@ -0,0 +1,35 @@ +using System; +using System.Globalization; +using System.Windows.Data; +using System.Windows.Media; + +namespace SpineViewer.Utils +{ + public class BackgroundToForegroundConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var color = Colors.White; + if (value is SolidColorBrush brush) + { + color = brush.Color; + } + else if (value is Color c) + { + color = c; + } + + if (color.A < 128) + return Brushes.Black; + + // 计算亮度 (使用标准加权公式) + double brightness = (0.299 * color.R + 0.587 * color.G + 0.114 * color.B) / 255.0; + return brightness < 0.5 ? Brushes.White : Brushes.Black; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/SpineViewer/ViewModels/Exporters/FFmpegVideoExporterViewModel.cs b/SpineViewer/ViewModels/Exporters/FFmpegVideoExporterViewModel.cs index c11b986..fb2f532 100644 --- a/SpineViewer/ViewModels/Exporters/FFmpegVideoExporterViewModel.cs +++ b/SpineViewer/ViewModels/Exporters/FFmpegVideoExporterViewModel.cs @@ -25,15 +25,14 @@ namespace SpineViewer.ViewModels.Exporters get => _format; set { - if (SetProperty(ref _format, value)) - { - OnPropertyChanged(nameof(EnableParamLoop)); - OnPropertyChanged(nameof(EnableParamQuality)); - OnPropertyChanged(nameof(EnableParamLossless)); - OnPropertyChanged(nameof(EnableParamApngPred)); - OnPropertyChanged(nameof(EnableParamCrf)); - OnPropertyChanged(nameof(EnableParamProfile)); - } + if (!SetProperty(ref _format, value)) + return; + OnPropertyChanged(nameof(EnableParamLoop)); + OnPropertyChanged(nameof(EnableParamQuality)); + OnPropertyChanged(nameof(EnableParamLossless)); + OnPropertyChanged(nameof(EnableParamApngPred)); + OnPropertyChanged(nameof(EnableParamCrf)); + OnPropertyChanged(nameof(EnableParamProfile)); } } protected FFmpegVideoExporter.VideoFormat _format = FFmpegVideoExporter.VideoFormat.Mp4; diff --git a/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs b/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs index 590b0fe..7a4041a 100644 --- a/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs +++ b/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs @@ -47,11 +47,6 @@ namespace SpineViewer.ViewModels.MainWindow /// private readonly SFML.Graphics.VertexArray _selectedBackgroundVertices = new(SFML.Graphics.PrimitiveType.Quads, 4); // XXX: 暂时未使用 Dispose 释放 - /// - /// 预览画面坐标轴颜色 - /// - private static readonly SFML.Graphics.Color _axisColor = new(220, 220, 220); - /// /// 坐标轴顶点缓冲区 /// @@ -178,10 +173,21 @@ namespace SpineViewer.ViewModels.MainWindow public Color BackgroundColor { get => Color.FromRgb(_backgroundColor.R, _backgroundColor.G, _backgroundColor.B); - set => SetProperty(BackgroundColor, value, v => _backgroundColor = new(value.R, value.G, value.B)); + set + { + if (!SetProperty(BackgroundColor, value, v => _backgroundColor = new(value.R, value.G, value.B))) + return; + var b = (0.299 * value.R + 0.587 * value.G + 0.114 * value.B) / 255.0; + _axisColor = b < 0.5 ? SFML.Graphics.Color.White : SFML.Graphics.Color.Black; + } } private SFML.Graphics.Color _backgroundColor = new(105, 105, 105); + /// + /// 预览画面坐标轴颜色 + /// + private SFML.Graphics.Color _axisColor = SFML.Graphics.Color.White; + public string BackgroundImagePath { get => _backgroundImagePath; diff --git a/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml b/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml index 58336f6..b0ffb83 100644 --- a/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml +++ b/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml @@ -5,6 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:hc="https://handyorg.github.io/handycontrol" xmlns:local="clr-namespace:SpineViewer.Views.ExporterDialogs" + xmlns:utils="clr-namespace:SpineViewer.Utils" xmlns:exporters="clr-namespace:SpineViewer.ViewModels.Exporters" d:DataContext="{d:DesignInstance Type=exporters:CustomFFmpegExporterViewModel}" mc:Ignorable="d" @@ -13,6 +14,9 @@ Height="800" ShowInTaskbar="False" WindowStartupLocation="CenterOwner"> + + + @@ -105,12 +109,20 @@