/// <summary>
 /// Выводит текст на экран. Должен вызываться последним после всех остальных операций по Рендерингу. Перед метордом Презент Свапчейна.
 /// </summary>
 /// <param name="text">Текст который будет рисоваться.</param>
 /// <param name="x">Отступ текста от левого края экрана, в пикселях.</param>
 /// <param name="y">Отступ текста от верхнего края экрана, в пикселях.</param>
 /// <param name="width">Ширина области в которую будет выводиться текст</param>
 /// <param name="height">Высота области в которую будет выводиться текст</param>
 public void DrawText(string text, float x = 0, float y = 0, float width = 400, float height = 300)
 {
     _RenderTarget2D.Target = d2dTarget;
     _RenderTarget2D.BeginDraw();
     _RenderTarget2D.DrawText(
         text,
         _TextFormat,
         new RectangleF(x, y, width, height),
         _SceneColorBrush,
         DrawTextOptions.Clip);
     _RenderTarget2D.EndDraw();
 }
Exemple #2
0
        void Render()
        {
            if (resized)
            {
                Resize();
                resized = false;
            }

            d2dDeviceContext.BeginDraw();
            d2dDeviceContext.Clear(Color4.White);

            d2dDeviceContext.PushAxisAlignedClip(new RectangleF(5, 5, Child.Width - 10, Child.Height - 10), AntialiasMode.Aliased);
            d2dDeviceContext.Transform = Matrix3x2.Translation(Child.Width / 2f / Scale + Translation.X, Child.Height / 2f / Scale + Translation.Y) * Matrix3x2.Scaling(Scale);

            d2dDeviceContext.AntialiasMode = AntialiasMode.Aliased;
            d2dDeviceContext.DrawLine(new Vector2(0, int.MinValue), new Vector2(0, int.MaxValue), RasterDrawBrush, 1 / Scale);
            d2dDeviceContext.DrawLine(new Vector2(int.MinValue, 0), new Vector2(int.MaxValue, 0), RasterDrawBrush, 1 / Scale);
            d2dDeviceContext.AntialiasMode = AntialiasMode.PerPrimitive;

            RenderGeometry();

            d2dDeviceContext.Transform = Matrix3x2.Identity;
            d2dDeviceContext.PopAxisAlignedClip();

            d2dDeviceContext.EndDraw();
            swapChain.Present(0, PresentFlags.None);
        }
Exemple #3
0
        public bool SendFrame(TimeSpan elapsedTime, int frameIndex)
        {
            var a   = Math.PI * elapsedTime.TotalSeconds;
            var h   = VideoFrameHeight - _ballEllipse.RadiusY;
            var y   = (float)(VideoFrameHeight - Math.Abs(Math.Sin(a) * h));
            var pos = new RawVector2(VideoFrameWidth * 0.5f, y);

            using (var df = TakeNextFrameForSending())
            {
                if (!df.TryGetFrame(out FrameD3D11 frame))
                {
                    return(false);
                }

                // TODO: Draw bouncing ball.
                _context2D.Target = frame.Bitmap;
                _context2D.BeginDraw();
                _context2D.Transform = Matrix3x2.Identity;
                _context2D.DrawBitmap(_backgroundBitmap, new RawRectangleF(0, 0, VideoFrameWidth, VideoFrameHeight),
                                      1, D2D1.BitmapInterpolationMode.NearestNeighbor);

                _context2D.Transform = BallPosition.HasValue
                    ? Matrix3x2.Translation(BallPosition.Value * new Vector2(VideoFrameWidth, VideoFrameHeight))
                    : Matrix3x2.Translation(pos);

                _context2D.FillEllipse(_ballEllipse, _ballBrush);
                _context2D.EndDraw();
                _context2D.Target = null;

                return(true);
            }
        }
Exemple #4
0
        public void DrawByte(byte[] bytes)
        {
            //System.Drawing.Graphics graphics = this.CreateGraphics();
            //graphics.DrawImage(bmp, 10, 10);


            /*d2dContext.Target = d2dTarget;
             * d2dContext.BeginDraw();
             * SolidColorBrush solidBrush = new SolidColorBrush(d2dContext, SharpDX.Color.Coral);
             * d2dContext.FillRectangle(new SharpDX.RectangleF(50, 50, 200, 200), solidBrush);*/

            //d2dTarget.CopyFromBitmap();
            //d2dContex

            d2dContext.Target = d2dTarget;
            d2dContext.BeginDraw();
            //d2dContext.
            //SolidColorBrush solidBrush = new SolidColorBrush(d2dContext, SharpDX.Color.Coral);
            //d2dContext.FillRectangle(new SharpDX.RectangleF(50, 50, 200, 200), solidBrush);

            //SharpDX.Rectangle rect = new SharpDX.Rectangle(0, 0, dWidth, dHeight);
            //d2dTarget.CopyFromMemory(bytes, dWidth * 4, rect);
            SharpDX.Rectangle rect = new SharpDX.Rectangle(0, 0, RenderWidth(), RenderHeight());
            d2dTarget.CopyFromMemory(bytes, RenderWidth() * 4, rect);

            //BitmapProperties bp = new BitmapProperties(new SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied));
            //int stride = bmp.Width * sizeof(int);
            //SharpDX.Direct2D1.Bitmap newBMP = Texture2D.FromStream<Texture2D>()

            /*using (SharpDX.DataStream tempStream = new SharpDX.DataStream(bmp.Height * stride, false, true))
             * {
             *  for (int y = 0; y < bmp.Height; y++)
             *  {
             *      for (int x = 0; x < bmp.Width; x++)
             *      {
             *          System.Drawing.Color c = bmp.GetPixel(x, y);
             *          int a = c.A;
             *          int r = (c.R * a) / 255;
             *          int g = (c.G * a) / 255;
             *          int b = (c.B * a) / 255;
             *          int bgra = b | (g << 8) | (r << 16) | (a << 24);
             *          tempStream.Write(bgra);
             *      }
             *  }
             *
             *  //d2dRenderTarget.BeginDraw();
             *  //newBMP = new SharpDX.Direct2D1.Bitmap(d2dRenderTarget, new Size2(bmp.Width, bmp.Height), tempStream, stride, bp);
             *  //d2dRenderTarget.EndDraw();
             * }*/


            //rect, 1.0f, SharpDX.Direct2D1.InterpolationMode.Linear
            //SharpDX.Mathematics.Interop.RawRectangleF rect = new SharpDX.Mathematics.Interop.RawRectangleF(50, 50, dWidth + 50, dHeight + 50);
            //d2dContext.DrawBitmap(bmp, rect, 1.0f, SharpDX.Direct2D1.InterpolationMode.Linear);
            //d2dContext.DrawBitmap(bmp, 1.0f, SharpDX.Direct2D1.InterpolationMode.Linear);
            d2dContext.EndDraw();

            //newBMP.Dispose();
        }
Exemple #5
0
 public void Run(Action renderCallback)
 {
     RenderLoop.Run(form, () => {
         d2dContext.BeginDraw();
         renderCallback.Invoke();
         d2dContext.EndDraw();
         swapChain.Present(0, PresentFlags.None);
     });
 }
Exemple #6
0
        /// <summary>
        /// Run our application until the user quits.
        /// </summary>
        public void Run()
        {
            // Make window active and hide mouse cursor.
            window.PointerCursor = null;
            window.Activate();

            // Infinite loop to prevent the application from exiting.
            while (true)
            {
                // Dispatch all pending events in the queue.
                window.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessAllIfPresent);

                // Quit if the users presses Escape key.
                if (window.GetAsyncKeyState(VirtualKey.Escape) == CoreVirtualKeyStates.Down)
                {
                    return;
                }

                // Set the Direct2D drawing target.
                d2dContext.Target = d2dTarget;

                // Clear the target.
                d2dContext.BeginDraw();
                d2dContext.Clear(Color.CornflowerBlue);

                // Draw a block of text that will be clipped against the specified layout rectangle.
                d2dContext.FillRectangle(new RectangleF(50, 50, 200, 200), backgroundBrush);
                d2dContext.DrawText("This text is long enough to overflow the designed region but will be clipped to the containing rectangle. Lorem ipsum dolor sit amet, consectetur adipiscing elit. ", textFormat, new RectangleF(50, 50, 200, 200), textBrush, DrawTextOptions.Clip);

                // Draw a block of text that will overflow the specified layout rectangle.
                d2dContext.FillRectangle(new RectangleF(50, 300, 200, 200), backgroundBrush);
                d2dContext.DrawText("However, this other text isn't going to be clipped: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean gravida dui id accumsan dictum.", textFormat, new RectangleF(50, 300, 200, 200), textBrush, DrawTextOptions.None);

                // Draw three lines of text with different measuring modes.
                d2dContext.FillRectangle(new RectangleF(300, 50, 400, 200), backgroundBrush);
                d2dContext.DrawText("MeasuringMode: Natural", textFormat, new RectangleF(300, 50, 400, 200), textBrush, DrawTextOptions.None, MeasuringMode.Natural);
                d2dContext.DrawText("MeasuringMode: GDI classic", textFormat, new RectangleF(300, 80, 400, 200), textBrush, DrawTextOptions.None, MeasuringMode.GdiClassic);
                d2dContext.DrawText("MeasuringMode: GDI natural", textFormat, new RectangleF(300, 110, 400, 200), textBrush, DrawTextOptions.None, MeasuringMode.GdiNatural);

                float layoutYOffset = (float)Math.Cos(layoutY) * 50.0f;

                // Draw moving text.
                d2dContext.FillRectangle(new RectangleF(300, 300, 400, 200), backgroundBrush);
                d2dContext.DrawTextLayout(new Vector2(300, 350 + layoutYOffset), textLayout1, textBrush);

                // Draw moving text without pixel snapping, thus giving a smoother movement.
                d2dContext.FillRectangle(new RectangleF(750, 300, 400, 200), backgroundBrush);
                d2dContext.DrawTextLayout(new Vector2(750, 350 + layoutYOffset), textLayout2, textBrush, DrawTextOptions.NoSnap);

                d2dContext.EndDraw();
                layoutY += 1.0f / 60.0f;

                // Present the current buffer to the screen.
                swapChain.Present(1, PresentFlags.None);
            }
        }
        public void DrawBytes(byte[] bytes)
        {
            d2dContext.Target = d2dTarget;
            d2dContext.BeginDraw();

            SharpDX.Rectangle rect = new SharpDX.Rectangle(0, 0, RenderWidth, RenderHeight);
            d2dTarget.CopyFromMemory(bytes, RenderWidth * 4, rect);

            d2dContext.EndDraw();
        }
Exemple #8
0
        public void RenderFrame()
        {
            if (!_isDisposed)
            {
                _deviceContext.BeginDraw();
                _deviceContext.Clear(SharpDX.Color.White);

                foreach (var visual in _visuals)
                {
                    visual.Render(this);
                }

                _deviceContext.EndDraw();
                _swapChain.Present(1, PresentFlags.None);
            }
        }
Exemple #9
0
        /// <summary>
        /// Run our application until the user quits.
        /// </summary>
        public void Run()
        {
            // Make window active and hide mouse cursor.
            window.PointerCursor = null;
            window.Activate();

            // Infinite loop to prevent the application from exiting.
            while (true)
            {
                // Dispatch all pending events in the queue.
                window.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessAllIfPresent);

                // Quit if the users presses Escape key.
                if (window.GetAsyncKeyState(VirtualKey.Escape) == CoreVirtualKeyStates.Down)
                {
                    return;
                }

                // Set the Direct2D drawing target.
                d2dContext.Target = d2dTarget;

                // Clear the target and draw some geometry with the brushes we created.
                d2dContext.BeginDraw();
                d2dContext.Clear(Color.CornflowerBlue);

                // Calculate the center of the screen
                int halfWidth  = this.swapChain.Description.ModeDescription.Width / 2;
                int halfHeight = this.swapChain.Description.ModeDescription.Height / 2;

                // Translate the origin of coordinates for drawing the bitmap filled rectangle
                d2dContext.Transform = Matrix3x2.Translation(halfWidth - 350, halfHeight);
                d2dContext.FillRectangle(new RectangleF(0, 0, 700, 70), terrainBrush);

                // Translate again for drawing the player bitmap
                d2dContext.Transform = Matrix3x2.Translation(halfWidth, halfHeight - playerBitmap.Size.Height);
                d2dContext.DrawBitmap(playerBitmap, 1.0f, SharpDX.Direct2D1.BitmapInterpolationMode.Linear);
                d2dContext.EndDraw();

                // Present the current buffer to the screen.
                swapChain.Present(1, PresentFlags.None);
            }
        }
Exemple #10
0
        public DXBitmapExportContext(int width, int height, float displayScale = 1, int dpi = 72, bool disposeBitmap = true)
            : base(width, height, dpi)
        {
            _disposeBitmap = disposeBitmap;

            if (_default3DDevice == null)
            {
                _default3DDevice = new d3d.Device(DriverType.Hardware, d3d.DeviceCreationFlags.VideoSupport | d3d.DeviceCreationFlags.BgraSupport);
                // default3DDevice = new d3d.Device(DriverType.Warp,  d3d.DeviceCreationFlags.BgraSupport);

                _default3DDevice1 = _default3DDevice.QueryInterface <d3d.Device1>();
                _dxgiDevice       = _default3DDevice1.QueryInterface <dxgi.Device>(); // get a reference to DXGI device

                _device2D = new d2.Device(_dxgiDevice);

                // initialize the DeviceContext - it will be the D2D render target
                _deviceContext = new d2.DeviceContext(_device2D, d2.DeviceContextOptions.None);
            }

            // specify a pixel format that is supported by both and WIC
            _pixelFormat = new d2.PixelFormat(dxgi.Format.B8G8R8A8_UNorm, d2.AlphaMode.Premultiplied);

            // create the d2d bitmap description using default flags
            var bitmapProps = new d2.BitmapProperties1(_pixelFormat, Dpi, Dpi,
                                                       d2.BitmapOptions.Target | d2.BitmapOptions.CannotDraw);

            // create our d2d bitmap where all drawing will happen
            _bitmap = new d2.Bitmap1(_deviceContext, new Size2(width, height), bitmapProps);

            // associate bitmap with the d2d context
            _deviceContext.Target = _bitmap;
            _deviceContext.BeginDraw();
            _deviceContext.Clear(new Color4 {
                Alpha = 0, Blue = 0, Green = 0, Red = 0
            });

            _canvas = new DXCanvas(_deviceContext)
            {
                DisplayScale = displayScale
            };
        }
Exemple #11
0
        /// <summary>
        /// Run our application until the user quits.
        /// </summary>
        public void Run()
        {
            // Make window active and hide mouse cursor.
            window.PointerCursor = null;
            window.Activate();

            // Infinite loop to prevent the application from exiting.
            while (true)
            {
                // Dispatch all pending events in the queue.
                window.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessAllIfPresent);

                // Quit if the users presses Escape key.
                if (window.GetAsyncKeyState(VirtualKey.Escape) == CoreVirtualKeyStates.Down)
                {
                    return;
                }

                // Set the Direct2D drawing target.
                d2dContext.Target = d2dTarget;

                // Clear the target and draw some geometry with the brushes we created.
                d2dContext.BeginDraw();
                d2dContext.Clear(Color.CornflowerBlue);
                d2dContext.FillRectangle(new RectangleF(50, 50, 450, 150), solidBrush);
                d2dContext.FillRoundedRectangle(new RoundedRectangle()
                {
                    Rect    = new RectangleF(50, 250, 450, 150),
                    RadiusX = 10,
                    RadiusY = 10
                }, linearGradientBrush);
                d2dContext.FillEllipse(new Ellipse(new Vector2(250, 525), 100, 100), radialGradientBrush);
                d2dContext.EndDraw();

                // Present the current buffer to the screen.
                swapChain.Present(1, PresentFlags.None);
            }
        }
        public async Task Render(IEnumerable <string> docNames, Stream outStream)
        {
            var ticket = Printing.Printing.CreateTicketForPrinter("Microsoft Print to PDF");

            var pms = ticket.PageMediaSize;

            var pageSize = new PxSize(
                (pms.Width != null) ? (float)pms.Width : 4962,
                (pms.Height != null) ? (float)pms.Height : 7014
                );

            using (var target = Printing.Printing.CreatePrintTarget(ticket, "Microsoft Print to PDF", outStream))
                using (var printControl = new D2D1.PrintControl(D2DDevice, WicFactory, target))
                    using (var dc = new D2D1.DeviceContext(D2DDevice, D2D1.DeviceContextOptions.None))
                    {
                        dc.DotsPerInch = new DX.Size2F(600, 600);

                        var pageStack                = new List <RendererDirect2D> ();
                        var pageY                    = 0;
                        var frameContext             = FrameContext.CreateRoot(pageSize);
                        D2D1.CommandList commandList = null;

                        foreach (var fn in docNames)
                        {
                            try
                            {
                                var document = await Loader.Load(new Uri(fn, UriKind.RelativeOrAbsolute));

                                var children = document.Children.Count;
                                if (children == 0)
                                {
                                    continue;
                                }
                                var svg = document.RootElement;
                                if (svg == null)
                                {
                                    continue;
                                }

                                var size       = svg.GetSize(frameContext, pageSize);
                                var viewPort   = svg.GetViewBox()?.AsRectangle() ?? size.AsRectangle();
                                var ratio      = svg.GetPreserveAspectRatio().CalcMatrix(size, viewPort);
                                var renderSize = new PxSize(
                                    (int)(0.5f + (viewPort.Width * ratio.M11)),
                                    (int)(0.5f + (viewPort.Height * ratio.M22))
                                    );

                                if (pageStack.Count > 0 && pageY + renderSize.Height > pms.Height)
                                {
                                    dc.EndDraw();
                                    commandList.Close();
                                    printControl.AddPage(commandList, new DX.Size2F(pageSize.Width, pageSize.Height));
                                    commandList.Dispose();
                                    foreach (var r in pageStack)
                                    {
                                        r.Dispose();
                                    }
                                    pageStack.Clear();
                                    pageY       = 0;
                                    commandList = null;
                                }

                                dc.Transform = DX.Matrix3x2.Translation(0, pageY);

                                if (commandList == null)
                                {
                                    commandList = new D2D1.CommandList(dc);
                                    dc.Target   = commandList;
                                    dc.BeginDraw();
                                }

                                var render = new RendererDirect2D(this, dc);
                                await render.GetRenderer(svg.ElementType)(svg, FrameContext.CreateRoot(renderSize), render);

                                pageStack.Add(render);

                                pageY += (int)renderSize.Height;
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("Skipping {0}", ex);
                                //throw ex;
                            }
                        }

                        if (pageStack.Count > 0)
                        {
                            dc.EndDraw();
                            commandList.Close();
                            printControl.AddPage(commandList, new DX.Size2F(pageSize.Width, pageSize.Height));
                            commandList.Dispose();
                            foreach (var r in pageStack)
                            {
                                r.Dispose();
                            }
                            pageStack.Clear();
                        }

                        // Send the job to the printing subsystem and discard
                        // printing-specific resources.
                        printControl.Close();
                    }
        }
 public void ClearScreen()
 {
     d2dContext.BeginDraw();
     d2dContext.Clear(Color.White);
     d2dContext.EndDraw();
 }
Exemple #14
0
        public void BeginDraw(Windows.Foundation.Rect updateRect)
        {
            // Express target area as a native RECT type.
            var updateRectNative = new Rectangle
            {
                Left   = (int)updateRect.Left,
                Top    = (int)updateRect.Top,
                Right  = (int)updateRect.Right,
                Bottom = (int)updateRect.Bottom
            };

            // Query for ISurfaceImageSourceNative interface.
            using (var sisNative = ComObject.QueryInterface <ISurfaceImageSourceNative>(this))
            {
                // Begin drawing - returns a target surface and an offset to use as the top left origin when drawing.
                try
                {
                    RawPoint offset;
                    using (var surface = sisNative.BeginDraw(updateRectNative, out offset))
                    {
                        // Create render target.
                        using (var bitmap = new Bitmap1(d2dContext, surface))
                        {
                            // Set context's render target.
                            d2dContext.Target = bitmap;
                        }

                        // Begin drawing using D2D context.
                        d2dContext.BeginDraw();

                        // Apply a clip and transform to constrain updates to the target update area.
                        // This is required to ensure coordinates within the target surface remain
                        // consistent by taking into account the offset returned by BeginDraw, and
                        // can also improve performance by optimizing the area that is drawn by D2D.
                        // Apps should always account for the offset output parameter returned by
                        // BeginDraw, since it may not match the passed updateRect input parameter's location.
                        d2dContext.PushAxisAlignedClip(
                            new RectangleF(
                                (offset.X),
                                (offset.Y),
                                (offset.X + (float)updateRect.Width),
                                (offset.Y + (float)updateRect.Height)
                                ),
                            AntialiasMode.Aliased
                            );

                        d2dContext.Transform = Matrix3x2.Translation(offset.X, offset.Y);
                    }
                }
                catch (SharpDXException ex)
                {
                    if (ex.ResultCode == SharpDX.DXGI.ResultCode.DeviceRemoved ||
                        ex.ResultCode == SharpDX.DXGI.ResultCode.DeviceReset)
                    {
                        // If the device has been removed or reset, attempt to recreate it and continue drawing.
                        CreateDeviceResources();
                        BeginDraw(updateRect);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
Exemple #15
0
 public void BeginRendering()
 {
     _d2D1DeviceContext.BeginDraw();
 }
Exemple #16
0
        static void Main()
        {
            // input and output files are supposed to be in the program folder
            var inputPath  = "Input.png";
            var outputPath = "Output.png";

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // INITIALIZATION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // initialize the D3D device which will allow to render to image any graphics - 3D or 2D
            var defaultDevice = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware,
                                                              d3d.DeviceCreationFlags.VideoSupport
                                                              | d3d.DeviceCreationFlags.BgraSupport
                                                              | d3d.DeviceCreationFlags.Debug); // take out the Debug flag for better performance

            var d3dDevice  = defaultDevice.QueryInterface <d3d.Device1>();                      // get a reference to the Direct3D 11.1 device
            var dxgiDevice = d3dDevice.QueryInterface <dxgi.Device>();                          // get a reference to DXGI device

            var d2dDevice = new d2.Device(dxgiDevice);                                          // initialize the D2D device

            var imagingFactory = new wic.ImagingFactory2();                                     // initialize the WIC factory

            // initialize the DeviceContext - it will be the D2D render target and will allow all rendering operations
            var d2dContext = new d2.DeviceContext(d2dDevice, d2.DeviceContextOptions.None);

            var dwFactory = new dw.Factory();

            // specify a pixel format that is supported by both D2D and WIC
            var d2PixelFormat = new d2.PixelFormat(dxgi.Format.R8G8B8A8_UNorm, d2.AlphaMode.Premultiplied);
            // if in D2D was specified an R-G-B-A format - use the same for wic
            var wicPixelFormat = wic.PixelFormat.Format32bppPRGBA;

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // IMAGE LOADING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            var decoder     = new wic.PngBitmapDecoder(imagingFactory);                            // we will load a PNG image
            var inputStream = new wic.WICStream(imagingFactory, inputPath, NativeFileAccess.Read); // open the image file for reading

            decoder.Initialize(inputStream, wic.DecodeOptions.CacheOnLoad);

            // decode the loaded image to a format that can be consumed by D2D
            var formatConverter = new wic.FormatConverter(imagingFactory);

            formatConverter.Initialize(decoder.GetFrame(0), wicPixelFormat);

            // load the base image into a D2D Bitmap
            //var inputBitmap = d2.Bitmap1.FromWicBitmap(d2dContext, formatConverter, new d2.BitmapProperties1(d2PixelFormat));

            // store the image size - output will be of the same size
            var inputImageSize = formatConverter.Size;
            var pixelWidth     = inputImageSize.Width;
            var pixelHeight    = inputImageSize.Height;

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // EFFECT SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // Effect 1 : BitmapSource - take decoded image data and get a BitmapSource from it
            var bitmapSourceEffect = new d2.Effects.BitmapSource(d2dContext);

            bitmapSourceEffect.WicBitmapSource = formatConverter;

            // Effect 2 : GaussianBlur - give the bitmapsource a gaussian blurred effect
            var gaussianBlurEffect = new d2.Effects.GaussianBlur(d2dContext);

            gaussianBlurEffect.SetInput(0, bitmapSourceEffect.Output, true);
            gaussianBlurEffect.StandardDeviation = 5f;

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // OVERLAY TEXT SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            var textFormat = new dw.TextFormat(dwFactory, "Arial", 15f); // create the text format of specified font configuration

            // draw a long text to show the automatic line wrapping
            var textToDraw = "Some long text to show the drawing of preformatted "
                             + "glyphs using DirectWrite on the Direct2D surface."
                             + " Notice the automatic wrapping of line if it exceeds desired width.";

            // create the text layout - this improves the drawing performance for static text
            // as the glyph positions are precalculated
            var textLayout = new dw.TextLayout(dwFactory, textToDraw, textFormat, 300f, 1000f);

            var textBrush = new d2.SolidColorBrush(d2dContext, Color.LightGreen);

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // RENDER TARGET SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // create the d2d bitmap description using default flags (from SharpDX samples) and 96 DPI
            var d2dBitmapProps = new d2.BitmapProperties1(d2PixelFormat, 96, 96, d2.BitmapOptions.Target | d2.BitmapOptions.CannotDraw);

            // the render target
            var d2dRenderTarget = new d2.Bitmap1(d2dContext, new Size2(pixelWidth, pixelHeight), d2dBitmapProps);

            d2dContext.Target = d2dRenderTarget; // associate bitmap with the d2d context

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // DRAWING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // slow preparations - fast drawing:
            d2dContext.BeginDraw();
            d2dContext.DrawImage(gaussianBlurEffect);
            d2dContext.DrawTextLayout(new Vector2(5f, 5f), textLayout, textBrush);
            d2dContext.EndDraw();

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // IMAGE SAVING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // delete the output file if it already exists
            if (System.IO.File.Exists(outputPath))
            {
                System.IO.File.Delete(outputPath);
            }

            // use the appropiate overload to write either to stream or to a file
            var stream = new wic.WICStream(imagingFactory, outputPath, NativeFileAccess.Write);

            // select the image encoding format HERE
            var encoder = new wic.PngBitmapEncoder(imagingFactory);

            encoder.Initialize(stream);

            var bitmapFrameEncode = new wic.BitmapFrameEncode(encoder);

            bitmapFrameEncode.Initialize();
            bitmapFrameEncode.SetSize(pixelWidth, pixelHeight);
            bitmapFrameEncode.SetPixelFormat(ref wicPixelFormat);

            // this is the trick to write D2D1 bitmap to WIC
            var imageEncoder = new wic.ImageEncoder(imagingFactory, d2dDevice);

            imageEncoder.WriteFrame(d2dRenderTarget, bitmapFrameEncode, new wic.ImageParameters(d2PixelFormat, 96, 96, 0, 0, pixelWidth, pixelHeight));

            bitmapFrameEncode.Commit();
            encoder.Commit();

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // CLEANUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // dispose everything and free used resources

            bitmapFrameEncode.Dispose();
            encoder.Dispose();
            stream.Dispose();
            textBrush.Dispose();
            textLayout.Dispose();
            textFormat.Dispose();
            formatConverter.Dispose();
            gaussianBlurEffect.Dispose();
            bitmapSourceEffect.Dispose();
            d2dRenderTarget.Dispose();
            inputStream.Dispose();
            decoder.Dispose();
            d2dContext.Dispose();
            dwFactory.Dispose();
            imagingFactory.Dispose();
            d2dDevice.Dispose();
            dxgiDevice.Dispose();
            d3dDevice.Dispose();
            defaultDevice.Dispose();

            // show the result
            System.Diagnostics.Process.Start(outputPath);
        }
        public bool SendFrame(TimeSpan elapsedTime)
        {
            using (var df = TakeNextFrameForSending())
            {
                if (!df.TryGetFrame(out BitmapFrameD2D1 frame))
                {
                    return(false);
                }

                _context2D.Target = frame.Bitmap;
                _context2D.BeginDraw();

                _context2D.Transform = Matrix3x2.Identity;
                _context2D.DrawBitmap(_backgroundBitmap, new RawRectangleF(0, 0, VideoFrameWidth, VideoFrameHeight),
                                      1, D2D1.BitmapInterpolationMode.NearestNeighbor);

                // Draw many balls to simulate high motion
                for (int i = 0; i < BallCount; ++i)
                {
                    var a   = 2 * Math.PI * elapsedTime.TotalSeconds + i * Math.PI / BallCount;
                    var h   = VideoFrameHeight - _ballEllipse.RadiusY;
                    var s   = (float)VideoFrameWidth / (BallCount + 1);
                    var y   = (float)(VideoFrameHeight - Math.Abs(Math.Sin(a) * h));
                    var pos = new RawVector2((i + 1) * s, y); // - _ballEllipse.RadiusX, y);

                    _context2D.Transform = MousePosition.HasValue
                        ? Matrix3x2.Translation(MousePosition.Value * new Vector2(VideoFrameWidth, VideoFrameHeight))
                        : Matrix3x2.Translation(pos);

                    _context2D.FillEllipse(_ballEllipse, _ballBrush);
                }

                if (_rulerOptions != null)
                {
                    _context2D.Transform = Matrix3x2.Identity;

                    // Draw the time markers and current time to measure latency
                    int markerCount  = _rulerOptions.MarkerCount;
                    int markerWidth  = _rulerOptions.MarkerWidth;
                    int markerHeight = _rulerOptions.MarkerHeight;
                    int markerOffset = markerWidth / 2;

                    var y = VideoFrameHeight - markerHeight;
                    _context2D.FillRectangle(new RectangleF(0, y, VideoFrameWidth, markerHeight), _timeRulerBrush);

                    for (int i = 0; i < markerCount; ++i)
                    {
                        var x = markerOffset + i * (VideoFrameWidth - markerWidth) / markerCount;
                        var b = i % 10 == 0 ? _timeMarkerBrush2 : _timeMarkerBrush1;

                        var r = new RectangleF(x - markerOffset, y, markerWidth, markerHeight);
                        _context2D.FillRectangle(r, b);
                    }

                    // Draw current time
                    {
                        var duration = _rulerOptions.Duration.TotalMilliseconds;
                        var t        = elapsedTime.TotalMilliseconds % duration;
                        var i        = (float)(t * markerCount / duration);

                        var x = markerOffset + i * (VideoFrameWidth - markerWidth) / markerCount;
                        var r = new RectangleF(x - markerOffset, y, markerWidth, markerHeight);
                        _context2D.FillRectangle(r, _currentTimeBrush);
                    }
                }

                _context2D.EndDraw();
                _context2D.Target = null;

                return(true);
            }
        }
Exemple #18
0
        public static MemoryStream Resize(System.IO.Stream source, int maxwidth, int maxheight, Action beforeDrawImage, Action afterDrawImage)
        {
            // initialize the D3D device which will allow to render to image any graphics - 3D or 2D
            var defaultDevice = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Warp,
                                                              d3d.DeviceCreationFlags.BgraSupport | d3d.DeviceCreationFlags.SingleThreaded | d3d.DeviceCreationFlags.PreventThreadingOptimizations);

            var d3dDevice = defaultDevice.QueryInterface<d3d.Device1>(); // get a reference to the Direct3D 11.1 device
            var dxgiDevice = d3dDevice.QueryInterface<dxgi.Device>(); // get a reference to DXGI device

            var d2dDevice = new d2.Device(dxgiDevice); // initialize the D2D device

            var imagingFactory = new wic.ImagingFactory2(); // initialize the WIC factory

            // initialize the DeviceContext - it will be the D2D render target and will allow all rendering operations
            var d2dContext = new d2.DeviceContext(d2dDevice, d2.DeviceContextOptions.None);

            var dwFactory = new dw.Factory();

            // specify a pixel format that is supported by both D2D and WIC
            var d2PixelFormat = new d2.PixelFormat(dxgi.Format.R8G8B8A8_UNorm, d2.AlphaMode.Premultiplied);
            // if in D2D was specified an R-G-B-A format - use the same for wic
            var wicPixelFormat = wic.PixelFormat.Format32bppPRGBA;

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // IMAGE LOADING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            var decoder = new wic.BitmapDecoder(imagingFactory,source, wic.DecodeOptions.CacheOnLoad);

            // decode the loaded image to a format that can be consumed by D2D
            var formatConverter = new wic.FormatConverter(imagingFactory);
            formatConverter.Initialize(decoder.GetFrame(0), wicPixelFormat);

            // store the image size - output will be of the same size
            var inputImageSize = formatConverter.Size;

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // RENDER TARGET SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // create the d2d bitmap description using default flags (from SharpDX samples) and 96 DPI
            var d2dBitmapProps = new d2.BitmapProperties1(d2PixelFormat, 96, 96, d2.BitmapOptions.Target | d2.BitmapOptions.CannotDraw);

            //Calculate size
            var resultSize = MathUtil.ScaleWithin(inputImageSize.Width,inputImageSize.Height,maxwidth,maxheight);
            var newWidth = resultSize.Item1;
            var newHeight = resultSize.Item2;

            // the render target
            var d2dRenderTarget = new d2.Bitmap1(d2dContext, new Size2(newWidth, newHeight), d2dBitmapProps);
            d2dContext.Target = d2dRenderTarget; // associate bitmap with the d2d context

            var bitmapSourceEffect = new d2.Effects.BitmapSourceEffect(d2dContext);
            bitmapSourceEffect.WicBitmapSource = formatConverter;

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // DRAWING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            beforeDrawImage();
            // slow preparations - fast drawing:
            d2dContext.BeginDraw();
            d2dContext.Transform = Matrix3x2.Scaling(new Vector2((float)(newWidth / (float)inputImageSize.Width), (float)(newHeight / (float)inputImageSize.Height)));
            d2dContext.DrawImage(bitmapSourceEffect, d2.InterpolationMode.HighQualityCubic);
            d2dContext.EndDraw();
            afterDrawImage();

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // IMAGE SAVING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            var ms = new MemoryStream();

            // use the appropiate overload to write either to stream or to a file
            var stream = new wic.WICStream(imagingFactory,ms);

            // select the image encoding format HERE
            var encoder = new wic.JpegBitmapEncoder(imagingFactory);
            encoder.Initialize(stream);

            var bitmapFrameEncode = new wic.BitmapFrameEncode(encoder);
            bitmapFrameEncode.Initialize();
            bitmapFrameEncode.SetSize(newWidth, newHeight);
            bitmapFrameEncode.SetPixelFormat(ref wicPixelFormat);

            // this is the trick to write D2D1 bitmap to WIC
            var imageEncoder = new wic.ImageEncoder(imagingFactory, d2dDevice);
            imageEncoder.WriteFrame(d2dRenderTarget, bitmapFrameEncode, new wic.ImageParameters(d2PixelFormat, 96, 96,  0, 0, newWidth, newHeight));

            bitmapFrameEncode.Commit();
            encoder.Commit();

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // CLEANUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // dispose everything and free used resources

            bitmapFrameEncode.Dispose();
            encoder.Dispose();
            stream.Dispose();
            formatConverter.Dispose();
            bitmapSourceEffect.Dispose();
            d2dRenderTarget.Dispose();
            decoder.Dispose();
            d2dContext.Dispose();
            dwFactory.Dispose();
            imagingFactory.Dispose();
            d2dDevice.Dispose();
            dxgiDevice.Dispose();
            d3dDevice.Dispose();
            defaultDevice.Dispose();
            return ms;
        }
        static void over()
        {
            var inputPath  = "Input.png";
            var outputPath = "output.png";

            // 그래픽을 랜더링할 장비를 추가 - 3D or 2D
            var defaultDevice = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware,
                                                              d3d.DeviceCreationFlags.VideoSupport
                                                              | d3d.DeviceCreationFlags.BgraSupport
                                                              | d3d.DeviceCreationFlags.None);
            var d3dDevice  = defaultDevice.QueryInterface <d3d.Device1>(); //get a refer to the D3D 11.1 device
            var dxgiDevice = d3dDevice.QueryInterface <dxgi.Device1>();    //get a refer to the DXGI device
            var d2dDevice  = new d2.Device(dxgiDevice);

            // DeviceContext를 초기화. D2D 렌더링 타겟이 될 것이고 모든 렌더링 작업을 허용
            var d2dContext = new d2.DeviceContext(d2dDevice, d2.DeviceContextOptions.None);
            var dwFactory  = new dw.Factory();


            //D2D, WIC 둘 다 지원되는 픽셀 형식 지정
            var d2PixelFormat = new d2.PixelFormat(dxgi.Format.R8G8B8A8_UNorm, d2.AlphaMode.Premultiplied);
            //RGBA형식 사용
            var wicPixelFormat = wic.PixelFormat.Format32bppPRGBA;



            //이미지 로딩
            var imagingFactory = new wic.ImagingFactory2();
            var decoder        = new wic.PngBitmapDecoder(imagingFactory);
            var inputStream    = new wic.WICStream(imagingFactory, inputPath, NativeFileAccess.Read);

            decoder.Initialize(inputStream, wic.DecodeOptions.CacheOnLoad);



            //다이렉트2D가 사용할수 있도록 디코딩
            var formatConverter = new wic.FormatConverter(imagingFactory);

            formatConverter.Initialize(decoder.GetFrame(0), wicPixelFormat);


            //기본 이미지를 D2D이미지로 로드
            //var inputBitmap = d2.Bitmap1.FromWicBitmap(d2dContext, formatConverter, new d2.BitmapProperties1(d2PixelFormat));

            //이미지 크기 저장
            var inputImageSize = formatConverter.Size;
            var pixelWidth     = inputImageSize.Width;
            var pixelHeight    = inputImageSize.Height;


            //Effect1 : BitpmapSource - 디코딩된 이미지 데이터를 가져오고 BitmapSource 가져오기
            var bitmapSourceEffect = new d2.Effects.BitmapSource(d2dContext);

            bitmapSourceEffect.WicBitmapSource = formatConverter;



            // Effect 2 : GaussianBlur - bitmapsource에 가우시안블러 효과 적용
            var gaussianBlurEffect = new d2.Effects.GaussianBlur(d2dContext);

            gaussianBlurEffect.SetInput(0, bitmapSourceEffect.Output, true);
            gaussianBlurEffect.StandardDeviation = 5f;



            //overlay text setup
            var textFormat = new dw.TextFormat(dwFactory, "Arial", 15f);

            //draw a long text to show the automatic line wrapping
            var textToDraw = "sime ling text..." + "text" + "dddd";

            //create the text layout - this imroves the drawing performance for static text
            // as the glyph positions are precalculated
            //윤곽선 글꼴 데이터에서 글자 하나의 모양에 대한 기본 단위를 글리프(glyph)라고 한다
            var textLayout = new dw.TextLayout(dwFactory, textToDraw, textFormat, 300f, 1000f);

            SharpDX.Mathematics.Interop.RawColor4 color = new SharpDX.Mathematics.Interop.RawColor4(255, 255, 255, 1);
            var textBrush = new d2.SolidColorBrush(d2dContext, color);



            //여기서부터 다시

            //render target setup

            //create the d2d bitmap description using default flags and 96 DPI
            var d2dBitmapProps = new d2.BitmapProperties1(d2PixelFormat, 96, 96, d2.BitmapOptions.Target | d2.BitmapOptions.CannotDraw);

            //the render target
            var d2dRenderTarget = new d2.Bitmap1(d2dContext, new Size2(pixelWidth, pixelHeight), d2dBitmapProps);

            d2dContext.Target = d2dRenderTarget; //associate bitmap with the d2d context



            //Drawing

            //slow preparations - fast drawing
            d2dContext.BeginDraw();
            d2dContext.DrawImage(gaussianBlurEffect, new SharpDX.Mathematics.Interop.RawVector2(100f, 100f));
            d2dContext.DrawTextLayout(new SharpDX.Mathematics.Interop.RawVector2(50f, 50f), textLayout, textBrush);
            d2dContext.EndDraw();

            //Image save

            //delete the output file if it already exists
            if (System.IO.File.Exists(outputPath))
            {
                System.IO.File.Delete(outputPath);
            }

            //use the appropiate overload to write either to tream or to a file
            var stream = new wic.WICStream(imagingFactory, outputPath, NativeFileAccess.Write);

            //select the image encoding format HERE
            var encoder = new wic.PngBitmapEncoder(imagingFactory);

            encoder.Initialize(stream);

            var bitmapFrameEncode = new wic.BitmapFrameEncode(encoder);

            bitmapFrameEncode.Initialize();
            bitmapFrameEncode.SetSize(pixelWidth, pixelHeight);
            bitmapFrameEncode.SetPixelFormat(ref wicPixelFormat);

            //this is the trick to write d2d1 bitmap to WIC
            var imageEncoder = new wic.ImageEncoder(imagingFactory, d2dDevice);

            imageEncoder.WriteFrame(d2dRenderTarget, bitmapFrameEncode, new wic.ImageParameters(d2PixelFormat, 96, 96, 0, 0, pixelWidth, pixelHeight));

            bitmapFrameEncode.Commit();
            encoder.Commit();

            //cleanup

            //dispose everything and free used resources
            bitmapFrameEncode.Dispose();
            encoder.Dispose();
            stream.Dispose();
            textBrush.Dispose();
            textLayout.Dispose();
            textFormat.Dispose();
            formatConverter.Dispose();
            //gaussianBlurEffect.Dispose();
            bitmapSourceEffect.Dispose();
            d2dRenderTarget.Dispose();
            inputStream.Dispose();
            decoder.Dispose();
            d2dContext.Dispose();
            dwFactory.Dispose();
            imagingFactory.Dispose();
            d2dDevice.Dispose();
            dxgiDevice.Dispose();
            d3dDevice.Dispose();
            defaultDevice.Dispose();

            //save
            System.Diagnostics.Process.Start(outputPath);
        }
Exemple #20
0
        static void Main()
        {
            // input and output files are supposed to be in the program folder
            var inputPath = "Input.png";
            var outputPath = "Output.png";

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // INITIALIZATION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // initialize the D3D device which will allow to render to image any graphics - 3D or 2D
            var defaultDevice = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware,
                                                              d3d.DeviceCreationFlags.VideoSupport
                                                              | d3d.DeviceCreationFlags.BgraSupport
                                                              | d3d.DeviceCreationFlags.Debug); // take out the Debug flag for better performance

            var d3dDevice = defaultDevice.QueryInterface<d3d.Device1>(); // get a reference to the Direct3D 11.1 device
            var dxgiDevice = d3dDevice.QueryInterface<dxgi.Device>(); // get a reference to DXGI device

            var d2dDevice = new d2.Device(dxgiDevice); // initialize the D2D device

            var imagingFactory = new wic.ImagingFactory2(); // initialize the WIC factory

            // initialize the DeviceContext - it will be the D2D render target and will allow all rendering operations
            var d2dContext = new d2.DeviceContext(d2dDevice, d2.DeviceContextOptions.None);

            var dwFactory = new dw.Factory();

            // specify a pixel format that is supported by both D2D and WIC
            var d2PixelFormat = new d2.PixelFormat(dxgi.Format.R8G8B8A8_UNorm, d2.AlphaMode.Premultiplied);
            // if in D2D was specified an R-G-B-A format - use the same for wic
            var wicPixelFormat = wic.PixelFormat.Format32bppPRGBA;

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // IMAGE LOADING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            var decoder = new wic.PngBitmapDecoder(imagingFactory); // we will load a PNG image
            var inputStream = new wic.WICStream(imagingFactory, inputPath, NativeFileAccess.Read); // open the image file for reading
            decoder.Initialize(inputStream, wic.DecodeOptions.CacheOnLoad);

            // decode the loaded image to a format that can be consumed by D2D
            var formatConverter = new wic.FormatConverter(imagingFactory);
            formatConverter.Initialize(decoder.GetFrame(0), wicPixelFormat);

            // load the base image into a D2D Bitmap
            //var inputBitmap = d2.Bitmap1.FromWicBitmap(d2dContext, formatConverter, new d2.BitmapProperties1(d2PixelFormat));

            // store the image size - output will be of the same size
            var inputImageSize = formatConverter.Size;
            var pixelWidth = inputImageSize.Width;
            var pixelHeight = inputImageSize.Height;

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // EFFECT SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // Effect 1 : BitmapSource - take decoded image data and get a BitmapSource from it
            var bitmapSourceEffect = new d2.Effects.BitmapSource(d2dContext);
            bitmapSourceEffect.WicBitmapSource = formatConverter;

            // Effect 2 : GaussianBlur - give the bitmapsource a gaussian blurred effect
            var gaussianBlurEffect = new d2.Effects.GaussianBlur(d2dContext);
            gaussianBlurEffect.SetInput(0, bitmapSourceEffect.Output, true);
            gaussianBlurEffect.StandardDeviation = 5f;

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // OVERLAY TEXT SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            var textFormat = new dw.TextFormat(dwFactory, "Arial", 15f); // create the text format of specified font configuration

            // draw a long text to show the automatic line wrapping
            var textToDraw = "Some long text to show the drawing of preformatted "
                             + "glyphs using DirectWrite on the Direct2D surface."
                             + " Notice the automatic wrapping of line if it exceeds desired width.";

            // create the text layout - this improves the drawing performance for static text
            // as the glyph positions are precalculated
            var textLayout = new dw.TextLayout(dwFactory, textToDraw, textFormat, 300f, 1000f);

            var textBrush = new d2.SolidColorBrush(d2dContext, Color.LightGreen);

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // RENDER TARGET SETUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // create the d2d bitmap description using default flags (from SharpDX samples) and 96 DPI
            var d2dBitmapProps = new d2.BitmapProperties1(d2PixelFormat, 96, 96, d2.BitmapOptions.Target | d2.BitmapOptions.CannotDraw);

            // the render target
            var d2dRenderTarget = new d2.Bitmap1(d2dContext, new Size2(pixelWidth, pixelHeight), d2dBitmapProps);
            d2dContext.Target = d2dRenderTarget; // associate bitmap with the d2d context

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // DRAWING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // slow preparations - fast drawing:
            d2dContext.BeginDraw();
            d2dContext.DrawImage(gaussianBlurEffect);
            d2dContext.DrawTextLayout(new Vector2(5f, 5f), textLayout, textBrush);
            d2dContext.EndDraw();

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // IMAGE SAVING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // delete the output file if it already exists
            if (System.IO.File.Exists(outputPath)) System.IO.File.Delete(outputPath);

            // use the appropiate overload to write either to stream or to a file
            var stream = new wic.WICStream(imagingFactory, outputPath, NativeFileAccess.Write);

            // select the image encoding format HERE
            var encoder = new wic.PngBitmapEncoder(imagingFactory);
            encoder.Initialize(stream);

            var bitmapFrameEncode = new wic.BitmapFrameEncode(encoder);
            bitmapFrameEncode.Initialize();
            bitmapFrameEncode.SetSize(pixelWidth, pixelHeight);
            bitmapFrameEncode.SetPixelFormat(ref wicPixelFormat);

            // this is the trick to write D2D1 bitmap to WIC
            var imageEncoder = new wic.ImageEncoder(imagingFactory, d2dDevice);
            imageEncoder.WriteFrame(d2dRenderTarget, bitmapFrameEncode, new wic.ImageParameters(d2PixelFormat, 96, 96, 0, 0, pixelWidth, pixelHeight));

            bitmapFrameEncode.Commit();
            encoder.Commit();

            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            // CLEANUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            // dispose everything and free used resources

            bitmapFrameEncode.Dispose();
            encoder.Dispose();
            stream.Dispose();
            textBrush.Dispose();
            textLayout.Dispose();
            textFormat.Dispose();
            formatConverter.Dispose();
            gaussianBlurEffect.Dispose();
            bitmapSourceEffect.Dispose();
            d2dRenderTarget.Dispose();
            inputStream.Dispose();
            decoder.Dispose();
            d2dContext.Dispose();
            dwFactory.Dispose();
            imagingFactory.Dispose();
            d2dDevice.Dispose();
            dxgiDevice.Dispose();
            d3dDevice.Dispose();
            defaultDevice.Dispose();

            // show the result
            System.Diagnostics.Process.Start(outputPath);
        }