Example #1
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            layer.ScaleOpacity(Opacity, Style);
            return(layer);
        }
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            using (var image = layer.ToMagickImage())
            {
                image.BackgroundColor = MagickColors.Transparent;

                var channels = Channels.None;
                if (ChannelA)
                {
                    channels = channels | Channels.Alpha;
                }
                if (ChannelR)
                {
                    channels = channels | Channels.Red;
                }
                if (ChannelG)
                {
                    channels = channels | Channels.Green;
                }
                if (ChannelB)
                {
                    channels = channels | Channels.Blue;
                }

                image.FilterType = FilterType.Lanczos;
                image.SelectiveBlur(Radius, Sigma, Threshold, channels);

                layer.CopyPixelsFrom(image.ToBitmapSource());
                return(layer);
            }
        }
Example #3
0
 public override BitmapBase Apply(Tank tank, BitmapBase layer)
 {
     if (FlipHorz)
         layer.FlipHorz();
     if (FlipVert)
         layer.FlipVert();
     return layer;
 }
Example #4
0
 public override BitmapBase Apply(Tank tank, BitmapBase layer)
 {
     if (ShiftX == 0 && ShiftY == 0)
         return layer;
     var result = new BitmapRam(layer.Width, layer.Height);
     result.DrawImage(layer, ShiftX, ShiftY);
     return result;
 }
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank  = renderTask.Tank;
            var  color = ColorHSV.FromColor(Color.GetColorWpf(tank));

            layer.Colorize(color.Hue, color.Saturation / 100.0, color.Value / 100.0 - 0.5, color.Alpha / 255.0);
            return(layer);
        }
 public override BitmapBase Apply(Tank tank, BitmapBase layer)
 {
     if (_blur == null || _blur.Radius != Radius)
         lock (this)
             if (_blur == null || _blur.Radius != Radius)
                 _blur = new GaussianBlur(Radius);
     layer.Blur(_blur, Edge);
     return layer;
 }
Example #7
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (ShiftX == 0 && ShiftY == 0)
            {
                return(layer);
            }
            var result = new BitmapRam(Math.Max(1, layer.Width + ShiftX), Math.Max(1, layer.Height + ShiftY));

            result.DrawImage(layer, ShiftX, ShiftY);
            return(result);
        }
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (Strength == 0)
            {
                return(layer);
            }

            int  totalAlpha      = 0;
            long totalBrightness = 0;

            using (layer.UseRead())
                unsafe
                {
                    for (int y = 0; y < layer.Height; y++)
                    {
                        byte *linePtr    = layer.Data + y * layer.Stride;
                        byte *lineEndPtr = linePtr + layer.Width * 4;
                        while (linePtr < lineEndPtr)
                        {
                            int brightness = *(linePtr) * 722 + *(linePtr + 1) * 7152 + *(linePtr + 2) * 2126;
                            totalBrightness += brightness * *(linePtr + 3);
                            totalAlpha      += *(linePtr + 3);
                            linePtr         += 4;
                        }
                    }
                }
            if (totalAlpha == 0)
            {
                return(layer);
            }

            using (var image = layer.ToMagickImage())
            {
                var averageBrightness = (double)totalBrightness * 100.0 / (double)totalAlpha / 255.0 / 10000.0;
                image.BackgroundColor = MagickColors.Transparent;
                double strength        = Strength / 100;
                double scaleValue      = 1 + (Brightness / averageBrightness - 1) * strength;
                double scaleSaturation = Saturation == SaturationMode.Zero ? 0 : 1;
                if (Saturation == SaturationMode.Reduce && scaleValue < 1)
                {
                    scaleSaturation = 1 - (1 - scaleValue * scaleValue) * strength;
                }
                image.Modulate(new Percentage(100 * scaleValue), new Percentage(100 * scaleSaturation), new Percentage(100));

                layer.CopyPixelsFrom(image.ToBitmapSource());
                return(layer);
            }
        }
Example #9
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            using (var image = layer.ToMagickImage())
            {
                image.BackgroundColor = MagickColors.Transparent;
                image.FilterType      = FilterType.Lanczos;
                image.AdaptiveBlur(Radius, Sigma);

                layer.CopyPixelsFrom(image.ToBitmapSource());
                return(layer);
            }
        }
Example #10
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (FlipHorz)
            {
                layer.FlipHorz();
            }
            if (FlipVert)
            {
                layer.FlipVert();
            }
            return(layer);
        }
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (_blur == null || _blur.Radius != Radius)
            {
                lock (this)
                    if (_blur == null || _blur.Radius != Radius)
                    {
                        _blur = new GaussianBlur(Radius);
                    }
            }
            layer.Blur(_blur, Edge);
            return(layer);
        }
Example #12
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank    = renderTask.Tank;
            var  outline = new BitmapRam(layer.Width, layer.Height);

            layer.GetOutline(outline, Color.GetColorWpf(tank), Threshold, Inside);
            if (KeepImage)
            {
                layer.DrawImage(outline);
                return(layer);
            }
            else
            {
                return(outline);
            }
        }
Example #13
0
        public unsafe override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank   = renderTask.Tank;
            var  bounds =
                Mode == ClipMode.ByPixels
                    ? layer.PreciseSize(PixelAlphaThreshold)
                : Mode == ClipMode.ByLayerBounds
                    ? PixelRect.FromMixed(0, 0, layer.Width, layer.Height)
                    : PixelRect.FromMixed(0, 0, Layer.ParentStyle.IconWidth, Layer.ParentStyle.IconHeight);

            using (layer.UseWrite())
            {
                int   count;
                byte *ptr;
                // Clip Top
                for (int y = 0; y < bounds.Top + ClipTop && y < layer.Height; y++)
                {
                    Ut.MemSet(layer.Data + y * layer.Stride, 0, layer.Width * 4);
                }
                // Clip Bottom
                for (int y = layer.Height - 1; y > bounds.Bottom - ClipBottom && y >= 0; y--)
                {
                    Ut.MemSet(layer.Data + y * layer.Stride, 0, layer.Width * 4);
                }
                // Clip Left
                count = Math.Min(bounds.Left + ClipLeft, layer.Width) * 4;
                ptr   = layer.Data;
                if (count > 0)
                {
                    for (int y = 0; y < layer.Height; y++, ptr += layer.Stride)
                    {
                        Ut.MemSet(ptr, 0, count);
                    }
                }
                // Clip Right
                count = Math.Min(layer.Width - 1 - bounds.Right + ClipRight, layer.Width) * 4;
                ptr   = layer.Data + layer.Width * 4 - count;
                if (count > 0)
                {
                    for (int y = 0; y < layer.Height; y++, ptr += layer.Stride)
                    {
                        Ut.MemSet(ptr, 0, count);
                    }
                }
            }
            return(layer);
        }
Example #14
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (Angle == 0)
            {
                return(layer);
            }

            using (var image = layer.ToMagickImage())
            {
                image.BackgroundColor = MagickColors.Transparent;
                image.Distort(DistortMethod.ScaleRotateTranslate, new double[] { RotateX, RotateY, Angle });

                layer.CopyPixelsFrom(image.ToBitmapSource());
                return(layer);
            }
        }
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (Hue == 0 && Saturation == 100 && Lightness == 100)
            {
                return(layer);
            }

            using (var image = layer.ToMagickImage())
            {
                image.BackgroundColor = MagickColors.Transparent;
                image.Modulate(new Percentage(Lightness), new Percentage(Saturation), new Percentage(Hue * 100.0 / 180.0 + 100));

                layer.CopyPixelsFrom(image.ToBitmapSource());
                return(layer);
            }
        }
Example #16
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (Amplitude == 0)
            {
                return(layer);
            }

            using (var image = layer.ToMagickImage())
            {
                image.BackgroundColor = MagickColors.Transparent;
                image.Wave(PixelInterpolateMethod.Bilinear, Amplitude, Length);

                layer.CopyPixelsFrom(image.ToBitmapSource());
                return(layer);
            }
        }
Example #17
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (GammaRed == 1 && GammaGreen == 1 && GammaBlue == 1)
            {
                return(layer);
            }

            using (var image = layer.ToMagickImage())
            {
                image.BackgroundColor = MagickColors.Transparent;
                image.GammaCorrect(GammaRed, Channels.Red);
                image.GammaCorrect(GammaGreen, Channels.Green);
                image.GammaCorrect(GammaBlue, Channels.Blue);
                //image.GammaCorrect(GammaRed, GammaGreen, GammaBlue);

                layer.CopyPixelsFrom(image.ToBitmapSource());
                return(layer);
            }
        }
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (Angle == 0)
            {
                return(layer);
            }

            var channels = Channels.None;

            if (ChannelA)
            {
                channels = channels | Channels.Alpha;
            }
            if (ChannelR)
            {
                channels = channels | Channels.Red;
            }
            if (ChannelG)
            {
                channels = channels | Channels.Green;
            }
            if (ChannelB)
            {
                channels = channels | Channels.Blue;
            }

            using (var image = layer.ToMagickImage())
            {
                image.BackgroundColor = MagickColors.Transparent;
                image.FilterType      = FilterType.Lanczos;
                image.RotationalBlur(Angle, channels);

                layer.CopyPixelsFrom(image.ToBitmapSource());
                return(layer);
            }
        }
Example #19
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (_blur == null || _blur.Radius != Radius)
            {
                lock (this)
                    if (_blur == null || _blur.Radius != Radius)
                    {
                        _blur = new GaussianBlur(Radius);
                    }
            }

            BitmapBase shadow = layer.ToBitmapRam();
            var        color  = Color.GetColorWpf(tank);

            shadow.ReplaceColor(color);
            shadow.Blur(_blur, BlurEdgeMode.Transparent);
            shadow.ScaleOpacity(Spread, OpacityStyle.Additive);
            shadow.Transparentize(color.A);
            layer.DrawImage(shadow, below: true);
            return(layer);
        }
Example #20
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (!(ChannelA || ChannelR || ChannelG || ChannelB))
            {
                return(layer);
            }

            using (var image = layer.ToMagickImage())
            {
                image.BackgroundColor = MagickColors.Transparent;

                var channels = Channels.None;
                if (ChannelA)
                {
                    channels = channels | Channels.Alpha;
                }
                if (ChannelR)
                {
                    channels = channels | Channels.Red;
                }
                if (ChannelG)
                {
                    channels = channels | Channels.Green;
                }
                if (ChannelB)
                {
                    channels = channels | Channels.Blue;
                }

                image.Negate(channels);

                layer.CopyPixelsFrom(image.ToBitmapSource());
                return(layer);
            }
        }
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (!(ChannelA || ChannelR || ChannelG || ChannelB) || (_Brightness == 0 && _Contrast == 0))
            {
                return(layer);
            }

            using (var image = layer.ToMagickImage())
            {
                image.BackgroundColor = MagickColors.Transparent;

                var channels = Channels.None;
                if (ChannelA)
                {
                    channels = channels | Channels.Alpha;
                }
                if (ChannelR)
                {
                    channels = channels | Channels.Red;
                }
                if (ChannelG)
                {
                    channels = channels | Channels.Green;
                }
                if (ChannelB)
                {
                    channels = channels | Channels.Blue;
                }

                image.BrightnessContrast(new Percentage(Brightness), new Percentage(Contrast), channels);

                layer.CopyPixelsFrom(image.ToBitmapSource());
                return(layer);
            }
        }
Example #22
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            if (!(ChannelA || ChannelR || ChannelG || ChannelB) || (BlackPoint == 0 && WhitePoint == 255 && MidPoint == 1))
            {
                return(layer);
            }

            using (var image = layer.ToMagickImage())
            {
                image.BackgroundColor = MagickColors.Transparent;

                var channels = Channels.None;
                if (ChannelA)
                {
                    channels = channels | Channels.Alpha;
                }
                if (ChannelR)
                {
                    channels = channels | Channels.Red;
                }
                if (ChannelG)
                {
                    channels = channels | Channels.Green;
                }
                if (ChannelB)
                {
                    channels = channels | Channels.Blue;
                }

                image.Level(new Percentage(BlackPoint), new Percentage(WhitePoint), MidPoint, channels);

                layer.CopyPixelsFrom(image.ToBitmapSource());
                return(layer);
            }
        }
Example #23
0
        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);
        }
Example #24
0
 public override BitmapBase Apply(Tank tank, BitmapBase layer)
 {
     var color = ColorHSV.FromColor(Color.GetColorWpf(tank));
     layer.Colorize(color.Hue, color.Saturation / 100.0, color.Value / 100.0 - 0.5, color.Alpha / 255.0);
     return layer;
 }
Example #25
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            var calculator = new SizeCalculator(renderTask, layer);
            Func <string, string> describe = property =>
                                             "*{0}:* {1}\n".Fmt(EggsML.Escape(App.Translation.Calculator.ErrLabel_Layer), EggsML.Escape((string.IsNullOrEmpty(Layer.Name) ? "" : (Layer.Name + " – ")) + Layer.TypeName)) +
                                             "*{0}:* {1}\n".Fmt(EggsML.Escape(App.Translation.Calculator.ErrLabel_Effect), EggsML.Escape((string.IsNullOrEmpty(Name) ? "" : (Name + " – ")) + TypeName)) +
                                             "*{0}:* {1}".Fmt(EggsML.Escape(App.Translation.Calculator.ErrLabel_Property), EggsML.Escape(property));

            double ParsedWidth  = Math.Max(0, calculator.Parse(Width, describe(WidthTr(App.Translation).DisplayName))),
                   ParsedHeight = Math.Max(0, calculator.Parse(Height, describe(HeightTr(App.Translation).DisplayName))),
                   ParsedX      = calculator.Parse(X, describe(XTr(App.Translation).DisplayName)),
                   ParsedY      = calculator.Parse(Y, describe(YTr(App.Translation).DisplayName));

            Tank tank   = renderTask.Tank;
            var  pixels = PixelRect.FromMixed(0, 0, layer.Width, layer.Height);

            if (ShowPixelBorders || PositionByPixels || (SizeByPixels && SizeMode2 != SizeMode2.NoChange && SizeMode2 != SizeMode2.ByPercentage))
            {
                pixels = layer.PreciseSize(PixelAlphaThreshold);
            }
            bool emptyPixels = pixels.Width <= 0 || pixels.Height <= 0;

            if (emptyPixels)
            {
                pixels = PixelRect.FromMixed(0, 0, layer.Width, layer.Height);
            }

            double scaleWidth, scaleHeight;
            int    sourceWidth  = SizeByPixels ? pixels.Width : layer.Width;
            int    sourceHeight = SizeByPixels ? pixels.Height : layer.Height;

            switch (SizeMode2)
            {
            case SizeMode2.NoChange:
                scaleWidth = scaleHeight = 1;
                break;

            case SizeMode2.ByPercentage:
                scaleWidth = scaleHeight = Percentage / 100.0;
                break;

            case SizeMode2.BySizeWidthOnly:
                scaleWidth = scaleHeight = ParsedWidth / (double)sourceWidth;
                break;

            case SizeMode2.BySizeHeightOnly:
                scaleWidth = scaleHeight = ParsedHeight / (double)sourceHeight;
                break;

            case SizeMode2.BySizeFit:
                scaleWidth = scaleHeight = Math.Min(ParsedWidth / (double)sourceWidth, ParsedHeight / (double)sourceHeight);
                break;

            case SizeMode2.BySizeStretch:
                scaleWidth  = ParsedWidth / (double)sourceWidth;
                scaleHeight = ParsedHeight / (double)sourceHeight;
                break;

            default:
                throw new Exception("7924688");
            }

            if (GrowShrinkMode == GrowShrinkMode.GrowOnly)
            {
                scaleWidth  = Math.Max(1.0, scaleWidth);
                scaleHeight = Math.Max(1.0, scaleHeight);
            }
            else if (GrowShrinkMode == GrowShrinkMode.ShrinkOnly)
            {
                scaleWidth  = Math.Min(1.0, scaleWidth);
                scaleHeight = Math.Min(1.0, scaleHeight);
            }

            var anchor       = (AnchorRaw)Anchor;
            int anchorWidth  = (int)Math.Ceiling((PositionByPixels ? pixels.Width : layer.Width) * scaleWidth);
            int anchorHeight = (int)Math.Ceiling((PositionByPixels ? pixels.Height : layer.Height) * scaleHeight);
            // Location of the top left corner of the anchored rectangle
            int tgtX = (int)ParsedX - (anchor.HasFlag(AnchorRaw.Right) ? anchorWidth - 1 : anchor.HasFlag(AnchorRaw.Center) ? (anchorWidth - 1) / 2 : 0);
            int tgtY = (int)ParsedY - (anchor.HasFlag(AnchorRaw.Bottom) ? anchorHeight - 1 : anchor.HasFlag(AnchorRaw.Mid) ? (anchorHeight - 1) / 2 : 0);
            // Location of the top left corner of the whole scaled layer image
            double x       = tgtX - (PositionByPixels ? pixels.Left * scaleWidth : 0);
            double y       = tgtY - (PositionByPixels ? pixels.Top * scaleHeight : 0);
            int    offsetX = (PositionByPixels ? pixels.Left : 0);
            int    offsetY = (PositionByPixels ? pixels.Top : 0);

            if (ShowLayerBorders || ShowPixelBorders)
            {
                using (var image = layer.ToMagickImage())
                {
                    image.Settings.StrokeWidth = 1;
                    if (ShowLayerBorders)
                    {
                        image.Settings.FillColor   = ImageMagick.MagickColors.Transparent;
                        image.Settings.StrokeColor = new ImageMagick.MagickColor("aqua");
                        image.Draw(new ImageMagick.DrawableRectangle(0, 0, layer.Width - 1, layer.Height - 1));
                    }
                    if (ShowPixelBorders && !emptyPixels)
                    {
                        image.Settings.FillColor   = ImageMagick.MagickColors.Transparent;
                        image.Settings.StrokeColor = new ImageMagick.MagickColor("red");
                        image.Draw(new ImageMagick.DrawableRectangle(pixels.Left, pixels.Top, pixels.Right, pixels.Bottom));
                    }
                    layer.CopyPixelsFrom(image.ToBitmapSource());
                }
            }
            BitmapResampler.Filter filter;
            switch (Filter)
            {
            case Filter.Auto: filter = null; break;

            case Filter.Mitchell: filter = new BitmapResampler.MitchellFilter(); break;

            case Filter.Bicubic: filter = new BitmapResampler.CatmullRomFilter(); break;

            case Filter.Lanczos: filter = new BitmapResampler.LanczosFilter(); break;

            case Filter.Sinc256: filter = new BitmapResampler.LanczosFilter(8); break;

            case Filter.Sinc1024: filter = new BitmapResampler.LanczosFilter(16); break;

            default: throw new Exception("SizePosEffect.Filter 4107");
            }
            layer = BitmapResampler.SizePos(layer, scaleWidth, scaleHeight, offsetX, offsetY, tgtX, tgtY, Math.Max(layer.Width, Layer.ParentStyle.IconWidth), Math.Max(layer.Height, Layer.ParentStyle.IconHeight), filter);
            if (ShowAnchor)
            {
                using (var image = layer.ToMagickImage())
                {
                    image.Settings.StrokeWidth = 1;
                    image.Settings.StrokeColor = new ImageMagick.MagickColor(255, 255, 0, 120);
                    image.Draw(new ImageMagick.DrawableLine((int)ParsedX - 1, (int)ParsedY, (int)ParsedX + 1, (int)ParsedY));
                    image.Draw(new ImageMagick.DrawableLine((int)ParsedX, (int)ParsedY - 1, (int)ParsedX, (int)ParsedY + 1));
                    layer.CopyPixelsFrom(image.ToBitmapSource());
                }
            }
            return(layer);
        }
Example #26
0
 public SizeCalculator(RenderTask renderTask, BitmapBase layer)
     : base()
 {
     _renderTask = renderTask;
     _layer      = layer;
 }
Example #27
0
        public unsafe override BitmapBase Apply(Tank tank, BitmapBase layer)
        {
            var bounds =
                Mode == ClipMode.ByPixels
                    ? layer.PreciseSize(PixelAlphaThreshold)
                : Mode == ClipMode.ByLayerBounds
                    ? PixelRect.FromMixed(0, 0, layer.Width, layer.Height)
                    : PixelRect.FromMixed(0, 0, Layer.ParentStyle.IconWidth, Layer.ParentStyle.IconHeight);

            using (layer.UseWrite())
            {
                int count;
                byte* ptr;
                // Clip Top
                for (int y = 0; y < bounds.Top + ClipTop && y < layer.Height; y++)
                    Ut.MemSet(layer.Data + y * layer.Stride, 0, layer.Width * 4);
                // Clip Bottom
                for (int y = layer.Height - 1; y > bounds.Bottom - ClipBottom && y >= 0; y--)
                    Ut.MemSet(layer.Data + y * layer.Stride, 0, layer.Width * 4);
                // Clip Left
                count = Math.Min(bounds.Left + ClipLeft, layer.Width) * 4;
                ptr = layer.Data;
                if (count > 0)
                    for (int y = 0; y < layer.Height; y++, ptr += layer.Stride)
                        Ut.MemSet(ptr, 0, count);
                // Clip Right
                count = Math.Min(layer.Width - 1 - bounds.Right + ClipRight, layer.Width) * 4;
                ptr = layer.Data + layer.Width * 4 - count;
                if (count > 0)
                    for (int y = 0; y < layer.Height; y++, ptr += layer.Stride)
                        Ut.MemSet(ptr, 0, count);
            }
            return layer;
        }
Example #28
0
 public override BitmapBase Apply(Tank tank, BitmapBase layer)
 {
     layer.ScaleOpacity(Opacity, Style);
     return layer;
 }
 public override BitmapBase Apply(Tank tank, BitmapBase layer)
 {
     var outline = new BitmapRam(layer.Width, layer.Height);
     layer.GetOutline(outline, Color.GetColorWpf(tank), Threshold, Inside);
     if (KeepImage)
     {
         layer.DrawImage(outline);
         return layer;
     }
     else
         return outline;
 }
Example #30
0
        public override BitmapBase Apply(Tank tank, BitmapBase layer)
        {
            if (_blur == null || _blur.Radius != Radius)
                lock (this)
                    if (_blur == null || _blur.Radius != Radius)
                        _blur = new GaussianBlur(Radius);

            BitmapBase shadow = layer.ToBitmapRam();
            var color = Color.GetColorWpf(tank);
            shadow.ReplaceColor(color);
            shadow.Blur(_blur, BlurEdgeMode.Transparent);
            shadow.ScaleOpacity(Spread, OpacityStyle.Additive);
            shadow.Transparentize(color.A);
            layer.DrawImage(shadow, below: true);
            return layer;
        }
Example #31
0
        public override BitmapBase Apply(Tank tank, BitmapBase layer)
        {
            var pixels = PixelRect.FromMixed(0, 0, layer.Width, layer.Height);
            if (ShowPixelBorders || PositionByPixels || (SizeByPixels && SizeMode2 != SizeMode2.NoChange && SizeMode2 != SizeMode2.ByPercentage))
                pixels = layer.PreciseSize(PixelAlphaThreshold);
            bool emptyPixels = pixels.Width <= 0 || pixels.Height <= 0;
            if (emptyPixels)
                pixels = PixelRect.FromMixed(0, 0, layer.Width, layer.Height);

            double scaleWidth, scaleHeight;
            int sourceWidth = SizeByPixels ? pixels.Width : layer.Width;
            int sourceHeight = SizeByPixels ? pixels.Height : layer.Height;
            switch (SizeMode2)
            {
                case SizeMode2.NoChange:
                    scaleWidth = scaleHeight = 1;
                    break;
                case SizeMode2.ByPercentage:
                    scaleWidth = scaleHeight = Percentage / 100.0;
                    break;
                case SizeMode2.BySizeWidthOnly:
                    scaleWidth = scaleHeight = Width / (double) sourceWidth;
                    break;
                case SizeMode2.BySizeHeightOnly:
                    scaleWidth = scaleHeight = Height / (double) sourceHeight;
                    break;
                case SizeMode2.BySizeFit:
                    scaleWidth = scaleHeight = Math.Min(Width / (double) sourceWidth, Height / (double) sourceHeight);
                    break;
                case SizeMode2.BySizeStretch:
                    scaleWidth = Width / (double) sourceWidth;
                    scaleHeight = Height / (double) sourceHeight;
                    break;
                default:
                    throw new Exception("7924688");
            }

            if (GrowShrinkMode == GrowShrinkMode.GrowOnly)
            {
                scaleWidth = Math.Max(1.0, scaleWidth);
                scaleHeight = Math.Max(1.0, scaleHeight);
            }
            else if (GrowShrinkMode == GrowShrinkMode.ShrinkOnly)
            {
                scaleWidth = Math.Min(1.0, scaleWidth);
                scaleHeight = Math.Min(1.0, scaleHeight);
            }

            var anchor = (AnchorRaw) Anchor;
            int anchorWidth = (int) Math.Ceiling((PositionByPixels ? pixels.Width : layer.Width) * scaleWidth);
            int anchorHeight = (int) Math.Ceiling((PositionByPixels ? pixels.Height : layer.Height) * scaleHeight);
            // Location of the top left corner of the anchored rectangle
            int tgtX = X - (anchor.HasFlag(AnchorRaw.Right) ? anchorWidth - 1 : anchor.HasFlag(AnchorRaw.Center) ? (anchorWidth - 1) / 2 : 0);
            int tgtY = Y - (anchor.HasFlag(AnchorRaw.Bottom) ? anchorHeight - 1 : anchor.HasFlag(AnchorRaw.Mid) ? (anchorHeight - 1) / 2 : 0);
            // Location of the top left corner of the whole scaled layer image
            double x = tgtX - (PositionByPixels ? pixels.Left * scaleWidth : 0);
            double y = tgtY - (PositionByPixels ? pixels.Top * scaleHeight : 0);

            var src = layer.ToBitmapGdi();
            if (ShowLayerBorders || ShowPixelBorders)
                using (var dc = System.Drawing.Graphics.FromImage(src.Bitmap))
                {
                    if (ShowLayerBorders)
                        dc.DrawRectangle(System.Drawing.Pens.Aqua, 0, 0, layer.Width - 1, layer.Height - 1);
                    if (ShowPixelBorders && !emptyPixels)
                        dc.DrawRectangle(System.Drawing.Pens.Red, pixels.Left, pixels.Top, pixels.Width - 1, pixels.Height - 1);
                }

            #if true
            // Using GDI: sharp-ish downscaling, but imprecise boundaries
            var result = new BitmapGdi(Math.Max(layer.Width, Layer.ParentStyle.IconWidth), Math.Max(layer.Height, Layer.ParentStyle.IconHeight));
            using (var dc = Graphics.FromImage(result.Bitmap))
            {
                dc.InterpolationMode = InterpolationMode.HighQualityBicubic;
                dc.DrawImage(src.Bitmap, (float) x, (float) y, (float) (src.Width * scaleWidth), (float) (src.Height * scaleHeight));
                if (ShowAnchor)
                    using (var pen = new Pen(Color.FromArgb(120, Color.Yellow), 0))
                    {
                        dc.DrawLine(pen, X - 1, Y, X + 1, Y);
                        dc.DrawLine(pen, X, Y - 1, X, Y + 1);
                    }
            }
            #else
            // Using WPF: precise boundaries but rather blurry downscaling
            var result = Ut.NewBitmapWpf(dc =>
            {
                var img = src.ToBitmapWpf().UnderlyingImage;

                var group = new System.Windows.Media.DrawingGroup();
                System.Windows.Media.RenderOptions.SetBitmapScalingMode(group, System.Windows.Media.BitmapScalingMode.Fant);
                group.Children.Add(new System.Windows.Media.ImageDrawing(img, new System.Windows.Rect(x, y, src.Width * scaleWidth, src.Height * scaleHeight)));
                dc.DrawDrawing(group);

                if (ShowTargetPosition)
                {
                    var pen = new System.Windows.Media.Pen(new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(200, 255, 255, 0)), 1);
                    dc.DrawLine(pen, new System.Windows.Point(X - 1 + 0.5, Y + 0.5), new System.Windows.Point(X + 1 + 0.5, Y + 0.5));
                    dc.DrawLine(pen, new System.Windows.Point(X + 0.5, Y - 1 + 0.5), new System.Windows.Point(X + 0.5, Y + 1 + 0.5));
                }
            }, Math.Max(layer.Width, Layer.Style.IconWidth), Math.Max(layer.Height, Layer.Style.IconHeight));
            #endif

            GC.KeepAlive(src);
            return result.ToBitmapRam();
        }
Example #32
0
        public unsafe override BitmapBase Apply(Tank tank, BitmapBase layer)
        {
            using (layer.UseWrite())
            {
                // Just scale the brightness and alpha channels so as to normalize the maximum value.
                // This is crude but gives good results; a better algorithm would try to fit the histogram
                // to a predefined standard by scaling non-linearly.
                double maxBrightness = -1;
                double maxAlpha = -1;
                for (int y = 0; y < layer.Height; y++)
                {
                    byte* ptr = layer.Data + y * layer.Stride;
                    byte* end = ptr + layer.Width * 4;
                    while (ptr < end)
                    {
                        byte alpha = *(ptr + 3);
                        if (alpha > 0) // there are a lot of non-black pixels in the fully-transparent regions
                        {
                            if (NormalizeBrightness)
                            {
                                double brightness = *(ptr + 0) * 0.0722 + *(ptr + 1) * 0.7152 + *(ptr + 2) * 0.2126;
                                if (brightness > maxBrightness)
                                    maxBrightness = brightness;
                            }
                            if (NormalizeAlpha)
                            {
                                if (alpha > maxAlpha)
                                    maxAlpha = alpha;
                            }
                        }
                        ptr += 4;
                    }
                }

                double scaleBrightness = (double) MaxBrightness / maxBrightness;
                double scaleAlpha = (double) MaxAlpha / maxAlpha;
                for (int y = 0; y < layer.Height; y++)
                {
                    byte* ptr = layer.Data + y * layer.Stride;
                    byte* end = ptr + layer.Width * 4;
                    while (ptr < end)
                    {
                        byte alpha = *(ptr + 3);
                        if (alpha > 0)
                        {
                            if (NormalizeBrightness)
                            {
                                if (Grayscale)
                                {
                                    double brightness = *(ptr + 0) * 0.0722 + *(ptr + 1) * 0.7152 + *(ptr + 2) * 0.2126;
                                    *(ptr + 0) = *(ptr + 1) = *(ptr + 2) = (byte) (brightness * scaleBrightness).ClipMax(255);
                                }
                                else
                                {
                                    // TODO: the clipping here alters the hue. Ideally the color should be clipped without altering hue, by increasing brightness until white.
                                    *(ptr + 0) = (byte) (*(ptr + 0) * scaleBrightness).ClipMax(255);
                                    *(ptr + 1) = (byte) (*(ptr + 1) * scaleBrightness).ClipMax(255);
                                    *(ptr + 2) = (byte) (*(ptr + 2) * scaleBrightness).ClipMax(255);
                                }
                            }
                            else if (Grayscale)
                            {
                                double brightness = *(ptr + 0) * 0.0722 + *(ptr + 1) * 0.7152 + *(ptr + 2) * 0.2126;
                                *(ptr + 0) = *(ptr + 1) = *(ptr + 2) = (byte) brightness;
                            }
                            if (NormalizeAlpha)
                            {
                                *(ptr + 3) = (byte) (alpha * scaleAlpha);
                            }
                        }
                        ptr += 4;
                    }
                }
            }
            return layer;
        }
        public unsafe override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank = renderTask.Tank;

            using (layer.UseWrite())
            {
                // Just scale the brightness and alpha channels so as to normalize the maximum value.
                // This is crude but gives good results; a better algorithm would try to fit the histogram
                // to a predefined standard by scaling non-linearly.
                double maxBrightness = -1;
                double maxAlpha      = -1;
                for (int y = 0; y < layer.Height; y++)
                {
                    byte *ptr = layer.Data + y * layer.Stride;
                    byte *end = ptr + layer.Width * 4;
                    while (ptr < end)
                    {
                        byte alpha = *(ptr + 3);
                        if (alpha > 0) // there are a lot of non-black pixels in the fully-transparent regions
                        {
                            if (NormalizeBrightness)
                            {
                                double brightness = *(ptr + 0) * 0.0722 + *(ptr + 1) * 0.7152 + *(ptr + 2) * 0.2126;
                                if (brightness > maxBrightness)
                                {
                                    maxBrightness = brightness;
                                }
                            }
                            if (NormalizeAlpha)
                            {
                                if (alpha > maxAlpha)
                                {
                                    maxAlpha = alpha;
                                }
                            }
                        }
                        ptr += 4;
                    }
                }

                double scaleBrightness = (double)MaxBrightness / maxBrightness;
                double scaleAlpha      = (double)MaxAlpha / maxAlpha;
                for (int y = 0; y < layer.Height; y++)
                {
                    byte *ptr = layer.Data + y * layer.Stride;
                    byte *end = ptr + layer.Width * 4;
                    while (ptr < end)
                    {
                        byte alpha = *(ptr + 3);
                        if (alpha > 0)
                        {
                            if (NormalizeBrightness)
                            {
                                if (Grayscale)
                                {
                                    double brightness = *(ptr + 0) * 0.0722 + *(ptr + 1) * 0.7152 + *(ptr + 2) * 0.2126;
                                    *(ptr + 0) = *(ptr + 1) = *(ptr + 2) = (byte)(brightness * scaleBrightness).ClipMax(255);
                                }
                                else
                                {
                                    // TODO: the clipping here alters the hue. Ideally the color should be clipped without altering hue, by increasing brightness until white.
                                    *(ptr + 0) = (byte)(*(ptr + 0) * scaleBrightness).ClipMax(255);
                                    *(ptr + 1) = (byte)(*(ptr + 1) * scaleBrightness).ClipMax(255);
                                    *(ptr + 2) = (byte)(*(ptr + 2) * scaleBrightness).ClipMax(255);
                                }
                            }
                            else if (Grayscale)
                            {
                                double brightness = *(ptr + 0) * 0.0722 + *(ptr + 1) * 0.7152 + *(ptr + 2) * 0.2126;
                                *(ptr + 0) = *(ptr + 1) = *(ptr + 2) = (byte)brightness;
                            }
                            if (NormalizeAlpha)
                            {
                                *(ptr + 3) = (byte)(alpha * scaleAlpha);
                            }
                        }
                        ptr += 4;
                    }
                }
            }
            return(layer);
        }