diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 65ee578e1..5ac2fc0a7 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -400,6 +400,7 @@ + diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AmbienceCreatorExtend.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AmbienceCreatorExtend.cs new file mode 100644 index 000000000..cd46673bf --- /dev/null +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbienceCreator/AmbienceCreatorExtend.cs @@ -0,0 +1,74 @@ +using System; +using Artemis.Profiles.Layers.Types.AmbientLight.Model; +using Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions; + +namespace Artemis.Profiles.Layers.Types.AmbientLight.AmbienceCreator +{ + public class AmbienceCreatorExtend : IAmbienceCreator + { + #region Methods + + public byte[] GetAmbience(byte[] pixels, int sourceWidth, int sourceHeight, + int targetWidth, int targetHeight, + AmbientLightPropertiesModel settings) + { + AvgColor[] colors = new AvgColor[targetWidth]; + for (int i = 0; i < colors.Length; i++) + colors[i] = new AvgColor(); + + int offsetLeft = settings.OffsetLeft + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Left) + ? pixels.DetectBlackBarLeft(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + : 0); + int offsetRight = settings.OffsetRight + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Right) + ? pixels.DetectBlackBarRight(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + : 0); + int offsetTop = settings.OffsetTop + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Top) + ? pixels.DetectBlackBarTop(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + : 0); + int offsetBottom = settings.OffsetBottom + (settings.BlackBarDetectionMode.HasFlag(BlackBarDetectionMode.Bottom) + ? pixels.DetectBlackBarBottom(sourceWidth, sourceHeight, settings.OffsetLeft, settings.OffsetRight, settings.OffsetTop, settings.OffsetBottom) + : 0); + + int effectiveSourceWidth = sourceWidth - offsetLeft - offsetRight; + int effectiveSourceHeight = sourceHeight - offsetTop - offsetBottom; + + int relevantSourceHeight = (int)Math.Round(effectiveSourceHeight * (settings.MirroredAmount / 100.0)); + int relevantOffsetTop = sourceHeight - offsetBottom - relevantSourceHeight; + + double widthPixels = effectiveSourceWidth / (double)targetWidth; + double heightPixels = relevantSourceHeight / (double)targetHeight; + + if (widthPixels <= 0 || heightPixels <= 0 || (relevantSourceHeight + relevantOffsetTop > sourceHeight) || effectiveSourceWidth > sourceWidth) + return colors.ToBGRArray(); + + for (int y = 0; y < relevantSourceHeight; y += 2) + { + int targetWidthIndex = 0; + double widthCounter = widthPixels; + + for (int x = 0; x < effectiveSourceWidth; x += 2) + { + if (x >= widthCounter) + { + widthCounter += widthPixels; + targetWidthIndex++; + } + + int colorsOffset = targetWidthIndex; + int sourceOffset = ((((relevantOffsetTop + y) * sourceWidth) + offsetLeft + x) * 4); + + AvgColor color = colors[colorsOffset]; + color.AddB(pixels[sourceOffset]); + color.AddG(pixels[sourceOffset + 1]); + color.AddR(pixels[sourceOffset + 2]); + } + } + + colors = colors.Flip(targetWidth, settings.FlipMode); + colors = colors.ExtendHeight(targetHeight); + return colors.ToBGRArray(); + } + + #endregion + } +} diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs index 9cdfdc856..6acc3877b 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/AmbientLightType.cs @@ -99,6 +99,7 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight switch (properties.AmbienceCreatorType) { case AmbienceCreatorType.Mirror: return _lastAmbienceCreator = new AmbienceCreatorMirror(); + case AmbienceCreatorType.Extend: return _lastAmbienceCreator = new AmbienceCreatorExtend(); default: throw new InvalidEnumArgumentException(); } } diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/AmbienceCreatorType.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/AmbienceCreatorType.cs index 9f4bc8acf..8f7f389e4 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/AmbienceCreatorType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/AmbienceCreatorType.cs @@ -5,6 +5,9 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model public enum AmbienceCreatorType { [Description("Mirror")] - Mirror + Mirror, + + [Description("Extend")] + Extend } } diff --git a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/AvgColorExtension.cs b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/AvgColorExtension.cs index 551f1c681..449072211 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/AvgColorExtension.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/AmbientLight/Model/Extensions/AvgColorExtension.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using Artemis.Profiles.Layers.Types.AmbientLight.AmbienceCreator; namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions @@ -20,6 +21,16 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.Model.Extensions return colors; } + public static AvgColor[] ExtendHeight(this AvgColor[] colors, int height) + { + AvgColor[] extended = new AvgColor[colors.Length * height]; + + for (int i = 0; i < height; i++) + Array.Copy(colors, 0, extended, i * colors.Length, colors.Length); + + return extended; + } + public static AvgColor[] FlipVertical(this AvgColor[] colors, int width) { if (colors == null || width <= 0) return colors;