1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Filter effect - Split up each filter into a seperate effect

BitmapBrush - Don't attempt to render while disposed
Effects - Only display movement cursor when mousing over icon
This commit is contained in:
SpoinkyNL 2020-06-16 19:14:00 +02:00
parent a62d5544cf
commit 480fae02b9
16 changed files with 329 additions and 162 deletions

View File

@ -10,6 +10,7 @@ namespace Artemis.Core.RGB.NET
public class BitmapBrush : AbstractDecoratable<IBrushDecorator>, IBrush, IDisposable
{
private readonly PluginSetting<int> _sampleSizeSetting;
private object _disposeLock;
#region Constructors
@ -17,6 +18,7 @@ namespace Artemis.Core.RGB.NET
{
_sampleSizeSetting = sampleSizeSetting;
Scale = scale;
_disposeLock = new object();
}
#endregion
@ -55,20 +57,27 @@ namespace Artemis.Core.RGB.NET
/// <inheritdoc />
public virtual void PerformRender(Rectangle rectangle, IEnumerable<BrushRenderTarget> renderTargets)
{
if (RenderedRectangle != rectangle || RenderedScale != Scale)
Bitmap = null;
lock (_disposeLock)
{
// Can happen during surface change
if (IsDisposed)
return;
RenderedRectangle = rectangle;
RenderedScale = Scale;
RenderedTargets.Clear();
if (RenderedRectangle != rectangle || RenderedScale != Scale)
Bitmap = null;
if (Bitmap == null)
CreateBitmap(RenderedRectangle);
RenderedRectangle = rectangle;
RenderedScale = Scale;
RenderedTargets.Clear();
if (_sampleSizeSetting.Value == 1)
TakeCenter(renderTargets);
else
TakeSamples(renderTargets);
if (Bitmap == null)
CreateBitmap(RenderedRectangle);
if (_sampleSizeSetting.Value == 1)
TakeCenter(renderTargets);
else
TakeSamples(renderTargets);
}
}
private void TakeCenter(IEnumerable<BrushRenderTarget> renderTargets)
@ -140,9 +149,15 @@ namespace Artemis.Core.RGB.NET
public void Dispose()
{
Bitmap?.Dispose();
lock (_disposeLock)
{
Bitmap?.Dispose();
IsDisposed = true;
}
}
public bool IsDisposed { get; set; }
#endregion
}
}

View File

@ -85,7 +85,7 @@
</StackPanel>
<!-- Type: LayerEffectRoot -->
<Grid Height="24" Cursor="SizeNS">
<Grid Height="24">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
@ -105,7 +105,12 @@
</Style.Triggers>
</Style>
</Grid.Style>
<materialDesign:PackIcon Grid.Column="0" Kind="{Binding LayerPropertyGroupViewModel.LayerPropertyGroup.LayerEffect.Descriptor.Icon}" Margin="0 5 5 0" />
<materialDesign:PackIcon
Grid.Column="0"
Cursor="SizeNS"
Kind="{Binding LayerPropertyGroupViewModel.LayerPropertyGroup.LayerEffect.Descriptor.Icon}"
Margin="0 5 5 0"
Background="Transparent"/>
<TextBlock Grid.Column="1" ToolTip="{Binding LayerPropertyGroupViewModel.LayerPropertyGroup.LayerEffect.Descriptor.Description}" Margin="0 5 0 0">
Effect
</TextBlock>

View File

@ -36,6 +36,7 @@
<ProjectReference Include="..\..\Artemis.UI.Shared\Artemis.UI.Shared.csproj" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(BuildingInsideVisualStudio)' == 'true'">
<Exec Command="echo Copying resources to plugin output directory&#xD;&#xA;XCOPY &quot;$(ProjectDir)Images&quot; &quot;$(TargetDir)Images&quot; /s /q /i /y&#xD;&#xA;XCOPY &quot;$(ProjectDir)Layouts&quot; &quot;$(TargetDir)Layouts&quot; /s /q /i /y&#xD;&#xA;echo Copying plugin to Artemis.UI output directory&#xD;&#xA;XCOPY &quot;$(TargetDir.TrimEnd('\'))&quot; &quot;$(SolutionDir)\Artemis.UI\$(OutDir)Plugins\$(ProjectName)&quot; /s /q /i /y" />
<Exec
Command="echo Copying resources to plugin output directory&#xD;&#xA;XCOPY &quot;$(ProjectDir)Images&quot; &quot;$(TargetDir)Images&quot; /s /q /i /y&#xD;&#xA;XCOPY &quot;$(ProjectDir)Layouts&quot; &quot;$(TargetDir)Layouts&quot; /s /q /i /y&#xD;&#xA;echo Copying plugin to Artemis.UI output directory&#xD;&#xA;XCOPY &quot;$(TargetDir.TrimEnd('\'))&quot; &quot;$(SolutionDir)\Artemis.UI\$(OutDir)Plugins\$(ProjectName)&quot; /s /q /i /y" />
</Target>
</Project>

View File

@ -0,0 +1,37 @@
using Artemis.Core.Plugins.LayerEffect.Abstract;
using SkiaSharp;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class BlurEffect : LayerEffect<BlurEffectProperties>
{
public override void EnableLayerEffect()
{
}
public override void DisableLayerEffect()
{
}
public override void Update(double deltaTime)
{
}
public override void PreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
paint.ImageFilter = SKImageFilter.CreateBlur(
Properties.BlurAmount.CurrentValue.Width,
Properties.BlurAmount.CurrentValue.Height,
paint.ImageFilter
);
}
public override void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
}
private void UpdateFilterType()
{
}
}
}

View File

@ -0,0 +1,25 @@
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.LayerProperties.Attributes;
using Artemis.Core.Models.Profile.LayerProperties.Types;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class BlurEffectProperties : LayerPropertyGroup
{
[PropertyDescription(Description = "The amount of blur to apply")]
public SKSizeLayerProperty BlurAmount { get; set; }
protected override void PopulateDefaults()
{
}
protected override void OnPropertiesInitialized()
{
}
private void UpdateVisibility()
{
}
}
}

View File

@ -0,0 +1,33 @@
using Artemis.Core.Plugins.LayerEffect.Abstract;
using SkiaSharp;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class DilateEffect : LayerEffect<DilateEffectProperties>
{
public override void EnableLayerEffect()
{
}
public override void DisableLayerEffect()
{
}
public override void Update(double deltaTime)
{
}
public override void PreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
paint.ImageFilter = SKImageFilter.CreateDilate(
(int) Properties.DilateRadius.CurrentValue.Width,
(int) Properties.DilateRadius.CurrentValue.Height,
paint.ImageFilter
);
}
public override void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
}
}
}

View File

@ -0,0 +1,20 @@
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.LayerProperties.Attributes;
using Artemis.Core.Models.Profile.LayerProperties.Types;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class DilateEffectProperties : LayerPropertyGroup
{
[PropertyDescription(Description = "The amount of dilation to apply")]
public SKSizeLayerProperty DilateRadius { get; set; }
protected override void PopulateDefaults()
{
}
protected override void OnPropertiesInitialized()
{
}
}
}

View File

@ -0,0 +1,33 @@
using Artemis.Core.Plugins.LayerEffect.Abstract;
using SkiaSharp;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class ErodeEffect : LayerEffect<ErodeEffectProperties>
{
public override void EnableLayerEffect()
{
}
public override void DisableLayerEffect()
{
}
public override void Update(double deltaTime)
{
}
public override void PreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
paint.ImageFilter = SKImageFilter.CreateErode(
(int) Properties.ErodeRadius.CurrentValue.Width,
(int) Properties.ErodeRadius.CurrentValue.Height,
paint.ImageFilter
);
}
public override void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
}
}
}

View File

@ -0,0 +1,20 @@
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.LayerProperties.Attributes;
using Artemis.Core.Models.Profile.LayerProperties.Types;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class ErodeEffectProperties : LayerPropertyGroup
{
[PropertyDescription(Description = "The amount of erode to apply")]
public SKSizeLayerProperty ErodeRadius { get; set; }
protected override void PopulateDefaults()
{
}
protected override void OnPropertiesInitialized()
{
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using Artemis.Core.Plugins.LayerEffect.Abstract;
using Artemis.UI.Shared.Utilities;
using SkiaSharp;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class FilterEffect : LayerEffect<FilterEffectProperties>
{
public override void EnableLayerEffect()
{
Properties.FilterType.BaseValueChanged += (sender, args) => UpdateFilterType();
UpdateFilterType();
}
private void UpdateFilterType()
{
if (HasBeenRenamed)
return;
Name = EnumUtilities.HumanizeValue(Properties.FilterType);
}
public override void DisableLayerEffect()
{
}
public override void Update(double deltaTime)
{
}
public override void PreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
if (Properties.FilterType == FilterType.Blur)
{
paint.ImageFilter = SKImageFilter.CreateBlur(
Properties.BlurAmount.CurrentValue.Width,
Properties.BlurAmount.CurrentValue.Height,
paint.ImageFilter
);
}
else if (Properties.FilterType == FilterType.Dilate)
{
paint.ImageFilter = SKImageFilter.CreateDilate(
(int) Properties.DilateRadius.CurrentValue.Width,
(int) Properties.DilateRadius.CurrentValue.Height,
paint.ImageFilter
);
}
else if (Properties.FilterType == FilterType.Erode)
{
paint.ImageFilter = SKImageFilter.CreateErode(
(int) Properties.ErodeRadius.CurrentValue.Width,
(int) Properties.ErodeRadius.CurrentValue.Height,
paint.ImageFilter
);
}
else if (Properties.FilterType == FilterType.Erode)
{
paint.ImageFilter = SKImageFilter.CreateErode(
(int) Properties.ErodeRadius.CurrentValue.Width,
(int) Properties.ErodeRadius.CurrentValue.Height,
paint.ImageFilter
);
}
else if (Properties.FilterType == FilterType.DropShadow)
{
paint.ImageFilter = SKImageFilter.CreateDropShadow(
Properties.ShadowOffset.CurrentValue.X,
Properties.ShadowOffset.CurrentValue.Y,
Properties.ShadowBlurAmount.CurrentValue.Width,
Properties.ShadowBlurAmount.CurrentValue.Height, Properties.ShadowColor,
SKDropShadowImageFilterShadowMode.DrawShadowAndForeground,
paint.ImageFilter
);
}
}
public override void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
}
}
}

View File

@ -1,62 +0,0 @@
using System;
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.LayerProperties.Attributes;
using Artemis.Core.Models.Profile.LayerProperties.Types;
using SkiaSharp;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class FilterEffectProperties : LayerPropertyGroup
{
[PropertyDescription]
public EnumLayerProperty<FilterType> FilterType { get; set; }
[PropertyDescription(Description = "The amount of blur to apply")]
public SKSizeLayerProperty BlurAmount { get; set; }
[PropertyDescription(Description = "The amount of dilation to apply")]
public SKSizeLayerProperty DilateRadius { get; set; }
[PropertyDescription(Description = "The amount of erode to apply")]
public SKSizeLayerProperty ErodeRadius { get; set; }
[PropertyDescription(Description = "The offset of the shadow")]
public SKPointLayerProperty ShadowOffset { get; set; }
[PropertyDescription(Description = "The amount of blur to apply to the shadow")]
public SKSizeLayerProperty ShadowBlurAmount { get; set; }
[PropertyDescription(Description = "The color of the shadow")]
public SKColorLayerProperty ShadowColor { get; set; }
protected override void PopulateDefaults()
{
ShadowBlurAmount.DefaultValue = new SKSize(5, 5);
ShadowColor.DefaultValue = new SKColor(50, 50, 50);
}
protected override void OnPropertiesInitialized()
{
FilterType.BaseValueChanged += (sender, args) => UpdateVisibility();
UpdateVisibility();
}
private void UpdateVisibility()
{
BlurAmount.IsHidden = FilterType != Filter.FilterType.Blur;
DilateRadius.IsHidden = FilterType != Filter.FilterType.Dilate;
ErodeRadius.IsHidden = FilterType != Filter.FilterType.Erode;
ShadowOffset.IsHidden = FilterType != Filter.FilterType.DropShadow;
ShadowBlurAmount.IsHidden = FilterType != Filter.FilterType.DropShadow;
ShadowColor.IsHidden = FilterType != Filter.FilterType.DropShadow;
}
}
public enum FilterType
{
Blur,
Dilate,
Erode,
DropShadow,
}
}

View File

@ -6,7 +6,11 @@ namespace Artemis.Plugins.LayerEffects.Filter
{
public override void EnablePlugin()
{
AddLayerEffectDescriptor<FilterEffect>("Filter", "A layer effect providing different types of filters", "ImageFilterFrames");
AddLayerEffectDescriptor<BlurEffect>("Blur", "A layer effect providing a blur filter effect", "BlurOn");
AddLayerEffectDescriptor<DilateEffect>("Dilate", "A layer effect providing a dilation filter effect", "EyePlus");
AddLayerEffectDescriptor<ErodeEffect>("Erode", "A layer effect providing an erode filter effect", "EyeMinus");
AddLayerEffectDescriptor<GlowEffect>("Glow", "A layer effect providing a glow filter effect", "BoxShadow");
AddLayerEffectDescriptor<GrayScaleEffect>("Gray-scale", "A layer effect providing a gray-scale filter effect", "InvertColors");
}
public override void DisablePlugin()

View File

@ -0,0 +1,36 @@
using Artemis.Core.Plugins.LayerEffect.Abstract;
using SkiaSharp;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class GlowEffect : LayerEffect<GlowEffectProperties>
{
public override void EnableLayerEffect()
{
}
public override void DisableLayerEffect()
{
}
public override void Update(double deltaTime)
{
}
public override void PreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
paint.ImageFilter = SKImageFilter.CreateDropShadow(
Properties.GlowOffset.CurrentValue.X,
Properties.GlowOffset.CurrentValue.Y,
Properties.GlowBlurAmount.CurrentValue.Width,
Properties.GlowBlurAmount.CurrentValue.Height, Properties.GlowColor,
SKDropShadowImageFilterShadowMode.DrawShadowAndForeground,
paint.ImageFilter
);
}
public override void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
}
}
}

View File

@ -0,0 +1,29 @@
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.LayerProperties.Attributes;
using Artemis.Core.Models.Profile.LayerProperties.Types;
using SkiaSharp;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class GlowEffectProperties : LayerPropertyGroup
{
[PropertyDescription(Description = "The offset of the glow")]
public SKPointLayerProperty GlowOffset { get; set; }
[PropertyDescription(Description = "The amount of blur to apply to the glow")]
public SKSizeLayerProperty GlowBlurAmount { get; set; }
[PropertyDescription(Description = "The color of the glow")]
public SKColorLayerProperty GlowColor { get; set; }
protected override void PopulateDefaults()
{
GlowBlurAmount.DefaultValue = new SKSize(25, 25);
GlowColor.DefaultValue = new SKColor(255, 255, 255);
}
protected override void OnPropertiesInitialized()
{
}
}
}

View File

@ -0,0 +1,35 @@
using Artemis.Core.Plugins.LayerEffect.Abstract;
using SkiaSharp;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class GrayScaleEffect : LayerEffect<GrayScaleEffectProperties>
{
public override void EnableLayerEffect()
{
}
public override void DisableLayerEffect()
{
}
public override void Update(double deltaTime)
{
}
public override void PreProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
paint.ImageFilter = SKImageFilter.CreateColorFilter(SKColorFilter.CreateColorMatrix(new[]
{
0.21f, 0.72f, 0.07f, 0, 0,
0.21f, 0.72f, 0.07f, 0, 0,
0.21f, 0.72f, 0.07f, 0, 0,
0, 0, 0, 1, 0
}), paint.ImageFilter);
}
public override void PostProcess(SKCanvas canvas, SKImageInfo canvasInfo, SKPath path, SKPaint paint)
{
}
}
}

View File

@ -0,0 +1,20 @@
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Profile.LayerProperties.Attributes;
using Artemis.Core.Models.Profile.LayerProperties.Types;
namespace Artemis.Plugins.LayerEffects.Filter
{
public class GrayScaleEffectProperties : LayerPropertyGroup
{
[PropertyDescription(Name = "Gray-scale strength (NYI)")]
public FloatLayerProperty GrayScaleStrength { get; set; }
protected override void PopulateDefaults()
{
}
protected override void OnPropertiesInitialized()
{
}
}
}