public static RenderTargetBitmap DrawText(this BitmapSource source, string[] text, DrawTextFormat textFormat)
        {
            var drawingVisual  = new DrawingVisual();
            var drawingContext = drawingVisual.RenderOpen();

            drawingContext.DrawImage(source, new Rect(0, 0, source.PixelWidth, source.PixelHeight));
            if (textFormat.ResizeOverflow == true)
            {
                textFormat.Size = AdjustFontSize(source, text, textFormat.Typeface, textFormat.Size, textFormat.Fill);
            }

            for (var i = 0; i < text.Length; i++)
            {
                var formatText = new FormattedText(text[i],
                                                   new CultureInfo("en-us"),
                                                   FlowDirection.LeftToRight,
                                                   textFormat.Typeface,
                                                   textFormat.Size,
                                                   new SolidColorBrush(textFormat.Fill),
                                                   source.DpiX / source.DpiY);

                var position = textFormat.Centered == true ? new Point((source.Width - formatText.Width) / 2 + textFormat.Adjusted.X, textFormat.Default.Y + textFormat.Adjusted.Y + i * formatText.Height) : new Point(textFormat.Default.X + textFormat.Adjusted.X, textFormat.Default.Y + textFormat.Adjusted.Y + i * formatText.Height);

                if (textFormat.Background == true)
                {
                    var rect = new Rect(new Point(0, (int)(textFormat.Default.Y + textFormat.Adjusted.Y + i * formatText.Height)), new Size(source.PixelWidth, formatText.Height));
                    drawingContext.DrawRectangle(new SolidColorBrush(textFormat.BackgroundColor ?? Colors.Transparent), new Pen(new SolidColorBrush(textFormat.BackgroundColor ?? Colors.Transparent), 1), rect);
                }

                RenderTextInformation(source, textFormat, drawingContext, formatText, position);
            }

            drawingContext.Close();
            var bmp = new RenderTargetBitmap(source.PixelWidth, source.PixelHeight, source.DpiX, source.DpiY, PixelFormats.Pbgra32);

            bmp.Render(drawingVisual);
            return(bmp);
        }
        public void RenderFrames()
        {
            if (_parent.font_size.Value == null || _parent.title_shift_h.Value == null || _parent.title_shift_v.Value == null)
            {
                return;
            }
            var fmt = DrawTextFormat.Make((CropControl.TglTextOverrideTF.IsChecked == true ? CropControl.Typeface : _parent.Typeface),
                                          (double)(CropControl.TglTextOverride.IsChecked == true ? CropControl.ov_font_size.Value ?? _parent.font_size.Value : _parent.font_size.Value),
                                          ((SolidColorBrush)_parent.fore_title_color_box.Fill).Color,
                                          _parent.chkb_bkg_title.IsChecked,
                                          _parent.chkb_otln.IsChecked,
                                          _parent.chkb_drpshdw.IsChecked,
                                          _parent.chkb_centering.IsChecked,
                                          true,
                                          new Point((double)_parent.title_shift_h.Value, (double)_parent.title_shift_v.Value),
                                          backgroundColor: ((SolidColorBrush)_parent.bkg_title_color_box.Fill).Color);
            BitmapSource titleFrame;
            BitmapSource frame;

            //attempt resize without stretching
            switch (CropControl.ImageCrop.SelectedIndex)
            {
            case 1:
                frame = _source.ResizedImage(_frame.Width, _frame.Height);
                break;

            case 2:
                frame = _source.ScaledCrop(_frame.Width, _frame.Height, CropControl.ImageScale, CropControl.CropX.Value,
                                           CropControl.CropY.Value);
                break;

            default:
                frame = _source.ResizeImageAndRatio(_frame.Width, _frame.Height, (int)CropControl.WidthAdjustment,
                                                    (int)CropControl.HeightAdjustment, CropControl.ImageScale);
                break;
            }


            if (frame == null)
            {
                System.Windows.MessageBox.Show(
                    "Image adjustments could not be made as the values given would cause errors in positioning.");
                return;
            }

            //force stretch to conform sizing
            if (frame.PixelWidth != _frame.Width || frame.PixelHeight != _frame.Height)
            {
                frame = frame.ResizedImage(_frame.Width, _frame.Height);
            }

            if (_parent.text_title.LineCount > 1)
            {
                string[] lines = new string[_parent.text_title.LineCount];
                for (int i = 0; i < _parent.text_title.LineCount; i++)
                {
                    lines[i] = _parent.text_title.GetLineText(i);
                }

                titleFrame = frame.DrawText(lines, fmt);
            }
            else
            {
                titleFrame = frame.DrawText(_parent.text_title.Text, fmt);
            }

            if (_parent.logo_file.Source != null)
            {
                double scale = ((double)(_parent.logo_scale.Value ?? 1) / 100);
                if (Math.Abs(scale) < 0.001)
                {
                    scale = 1;
                }
                double sWidth = _parent.logo_file.Source.Width * scale;

                double sHeight = _parent.logo_file.Source.Height * scale;

                BitmapSource scaledLogo = ((BitmapSource)_parent.logo_file.Source).ResizedImage((int)sWidth, (int)sHeight);
                if (scaledLogo.PixelWidth > _frame.Width || scaledLogo.PixelHeight > _frame.Height)
                {
                    scaledLogo = scaledLogo.ScaleImage(_frame.Width, _frame.Height);
                }

                double pointX = (_frame.Width - scaledLogo.PixelWidth) / 2 + (_parent.logo_shift_w.Value ?? 0);
                double pointY = (_frame.Height - scaledLogo.PixelHeight) / 2 + (_parent.logo_shift_h.Value ?? 0);
                frame      = frame.DrawImage(scaledLogo, new Point(pointX, pointY));
                titleFrame = titleFrame.DrawImage(scaledLogo, new Point(pointX, pointY));
            }

            if (_parent.banner_file.Source != null)
            {
                BitmapSource scaledBanner = ((BitmapSource)_parent.banner_file.Source).ScaleImage(_frame.Width, _frame.Height);

                titleFrame = titleFrame.DrawImage(scaledBanner, new Point(0, titleFrame.Height - scaledBanner.Height));
            }

            KeyImage.Source   = frame;
            TitleImage.Source = titleFrame;
        }
        private static void RenderTextInformation(this BitmapSource source, DrawTextFormat textFormat, DrawingContext drawingContext, FormattedText formatText, Point position)
        {
            var shadow = Color.FromArgb(125, 0, 0, 0);

            switch (textFormat.DropShadow)
            {
            case true when textFormat.Outline == true:
            {
                const int distance = 2;
                for (var offset = 1; 0 <= offset; offset--)
                {
                    var point = new Point()
                    {
                        X = position.X + offset * distance,
                        Y = position.Y + offset * distance
                    };

                    var geo = formatText.BuildGeometry(point);
                    drawingContext.DrawGeometry(new SolidColorBrush(offset < 1 ? textFormat.Fill : shadow), new Pen(new SolidColorBrush(textFormat.Edge ?? shadow), 2), geo);
                }

                break;
            }

            case true:
            {
                const int distance   = 2;
                var       shadowText = new FormattedText(formatText.Text,
                                                         new CultureInfo("en-us"),
                                                         FlowDirection.LeftToRight,
                                                         textFormat.Typeface,
                                                         textFormat.Size,
                                                         new SolidColorBrush(shadow),
                                                         source.DpiX / source.DpiY);
                for (var offset = 1; 0 <= offset; offset--)
                {
                    var point = new Point()
                    {
                        X = position.X + offset * distance,
                        Y = position.Y + offset * distance
                    };

                    drawingContext.DrawText(offset < 1 ? formatText : shadowText, point);
                }

                break;
            }

            default:
            {
                if (textFormat.Outline == true)
                {
                    var geo = formatText.BuildGeometry(position);
                    drawingContext.DrawGeometry(new SolidColorBrush(textFormat.Fill), new Pen(new SolidColorBrush(textFormat.Edge ?? Colors.Black), 2), geo);
                }
                else
                {
                    drawingContext.DrawText(formatText, position);
                }

                break;
            }
            }
        }