/Effects/MaskLayerEffect.cs
C# | 96 lines | 89 code | 7 blank | 0 comment | 11 complexity | 44aefeb817fcef7a54346ab75bbe77e8 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-3.0, CC-BY-SA-3.0
- using System;
- using System.IO;
- using System.Linq;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Windows.Media.Imaging;
- using ImageMagick;
- using RT.Util.Lingo;
- using RT.Util.Serialization;
-
- namespace TankIconMaker.Effects
- {
- [TypeConverter(typeof(MaskModeTranslation.Conv))]
- enum MaskMode
- {
- Combined,
- Opacity,
- Grayscale
- }
-
- class MaskLayerEffect : EffectBase
- {
- public override int Version { get { return 1; } }
- public override string TypeName { get { return App.Translation.EffectMaskLayer.EffectName; } }
- public override string TypeDescription { get { return App.Translation.EffectMaskLayer.EffectDescription; } }
-
- public string MaskLayerId { get; set; }
- public static MemberTr MaskLayerIdTr(Translation tr) { return new MemberTr(tr.Category.Mask, tr.EffectMaskLayer.MaskLayerId); }
-
- public MaskMode MaskMode { get; set; }
- public static MemberTr MaskModeTr(Translation tr) { return new MemberTr(tr.Category.Mask, tr.EffectMaskLayer.MaskMode); }
-
- public bool Invert { get; set; }
- public static MemberTr InvertTr(Translation tr) { return new MemberTr(tr.Category.Mask, tr.EffectMaskLayer.InvertTr); }
-
- public MaskLayerEffect()
- {
- MaskLayerId = string.Empty;
- MaskMode = Effects.MaskMode.Combined;
- Invert = false;
- }
-
- public unsafe override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
- {
- Tank tank = renderTask.Tank;
- LayerBase maskLayer;
- if (string.IsNullOrEmpty(MaskLayerId))
- return layer;
- maskLayer = renderTask.Style.Layers.FirstOrDefault(x => x.Id == MaskLayerId);
- if (maskLayer == null)
- throw new StyleUserError(App.Translation.EffectMaskLayer.ErrorInvalidId.Fmt(MaskLayerId));
- if (renderTask.IsLayerAlreadyReferenced(maskLayer))
- throw new StyleUserError(App.Translation.EffectMaskLayer.ErrorRecursiveLayerReference.Fmt(MaskLayerId));
- var maskImg = renderTask.RenderLayer(maskLayer);
- using (layer.UseWrite())
- {
- using (maskImg.UseRead())
- {
- for (int i = 0; i < layer.Width; ++i)
- {
- for (int j = 0; j < layer.Height; ++j)
- {
- decimal alpha = 0;
- if (i < maskImg.Width && j < maskImg.Height)
- {
- switch (MaskMode)
- {
- case Effects.MaskMode.Opacity:
- alpha = maskImg.Data[i * 4 + maskImg.Stride * j + 3];
- break;
- case Effects.MaskMode.Grayscale:
- alpha = (maskImg.Data[i * 4 + maskImg.Stride * j]
- + maskImg.Data[i * 4 + maskImg.Stride * j + 1]
- + maskImg.Data[i * 4 + maskImg.Stride * j + 2]
- ) / 3;
- break;
- case Effects.MaskMode.Combined:
- alpha = (maskImg.Data[i * 4 + maskImg.Stride * j]
- + maskImg.Data[i * 4 + maskImg.Stride * j + 1]
- + maskImg.Data[i * 4 + maskImg.Stride * j + 2]
- ) / 3 * maskImg.Data[i * 4 + maskImg.Stride * j + 3] / 255m;
- break;
- }
- }
- if (Invert)
- alpha = 255m - alpha;
- var opacity = layer.Data[i * 4 + layer.Stride * j + 3] * (alpha / 255m);
- layer.Data[i * 4 + layer.Stride * j + 3] = (byte) opacity;
- }
- }
- }
- }
- return layer;
- }
- }
- }