/// <summary>
        /// Resizes the SurfaceImage with the given size and redraws the SurfaceImage by loading
        /// image from the new Uri.
        /// </summary>
        /// <param name="uri">Uri of the image to be loaded onto the SurfaceImage.</param>
        /// <param name="size">New size of the SurfaceImage</param>
        /// <param name="options">Describes the image's resize and alignment options in the allocated space.</param>
        /// <returns>Task</returns>
        public async Task RedrawAsync(Uri uri, Size size, CompositionSurfaceImageOptions options)
        {
            // If the given Uri differs from the previously stored Uri
            // dispose the existing canvasBitmap
            if (!_uri.IsEqualTo(uri))
            {
                _canvasBitmap?.Dispose();
                _canvasBitmap = null;
            }

            // Set the image options
            Options = options;
            // Resize the surface only if AutoResize option is disabled
            if (!Options.AutoResize)
            {
                // resize the SurfaceImage
                _generator.ResizeDrawingSurface(_surfaceLock, _surface, size);
                // Set the size
                Size = _surface?.Size ?? new Size(0, 0);
            }
            // Set the new Uri of the image to be loaded
            _uri = uri;
            // Reload the SurfaceImage
            await RedrawSurfaceImageInternalAsync();
        }
 /// <summary>
 /// Redraws the SurfaceImage with the given image options
 /// </summary>
 /// <param name="options">Describes the image's resize and alignment options in the allocated space.</param>
 /// <returns>Task</returns>
 public void Redraw(CompositionSurfaceImageOptions options)
 {
     // Set the image options
     Options = options;
     // Redraw the SurfaceImage
     RedrawSurfaceImageInternal();
 }
 /// <summary>
 /// Disposes the resources used by the SurfaceImage
 /// </summary>
 public void Dispose()
 {
     _surface?.Dispose();
     if (_generator != null)
     {
         _generator.DeviceReplaced -= OnDeviceReplaced;
     }
     _canvasBitmap?.Dispose();
     _canvasBitmap = null;
     _surface      = null;
     _generator    = null;
     _uri          = null;
     Options       = null;
 }
 /// <summary>
 /// Resizes the SurfaceImage to the new size.
 /// </summary>
 /// <param name="size">New size of the SurfaceImage</param>
 /// <param name="options">Describes the image's resize and alignment options in the allocated space.</param>
 public void Resize(Size size, CompositionSurfaceImageOptions options)
 {
     // Set the image options
     Options = options;
     // Resize the surface only if AutoResize option is disabled
     if (!Options.AutoResize)
     {
         // resize the SurfaceImage
         _generator.ResizeDrawingSurface(_surfaceLock, _surface, size);
         // Set the size
         Size = _surface?.Size ?? new Size(0, 0);
     }
     // resize the SurfaceImage
     RedrawSurfaceImageInternal();
 }
        /// <summary>
        /// Redraws the SurfaceImage by loading image from the new Uri and image options
        /// </summary>
        /// <param name="uri">Uri of the image to be loaded on to the image surface.</param>
        /// <param name="options">Describes the image's resize and alignment options in the allocated space.</param>
        /// <returns>Task</returns>
        public Task RedrawAsync(Uri uri, CompositionSurfaceImageOptions options)
        {
            // If the given Uri differs from the previously stored Uri
            // dispose the existing canvasBitmap
            if (!_uri.IsEqualTo(uri))
            {
                _canvasBitmap?.Dispose();
                _canvasBitmap = null;
            }

            // Set the new Uri of the image to be loaded
            _uri = uri;
            // Set the image options
            Options = options;
            // Reload the SurfaceImage
            return(RedrawSurfaceImageInternalAsync());
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="generator">ICompositionMaskGeneratorInternal object</param>
        /// <param name="uri">Uri of the image to be loaded onto the SurfaceImage.</param>
        /// <param name="size">Size of the SurfaceImage</param>
        /// <param name="options">Describes the image's resize and alignment options in the allocated space.</param>
        public CompositionSurfaceImage(ICompositionGeneratorInternal generator, Uri uri, Size size, CompositionSurfaceImageOptions options)
        {
            if (generator == null)
            {
                throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!");
            }

            _generator   = generator;
            _surfaceLock = new object();
            // Create the Surface of the SurfaceImage
            _surface      = _generator.CreateDrawingSurface(_surfaceLock, size);
            Size          = _surface?.Size ?? new Size(0, 0);
            _uri          = uri;
            _canvasBitmap = null;
            // Set the image options
            Options = options;
            // Subscribe to DeviceReplaced event
            _generator.DeviceReplaced += OnDeviceReplaced;
        }
Esempio n. 7
0
        /// <summary>
        /// Resizes the SurfaceImage to the given size and redraws the SurfaceImage by loading
        /// image from the new Uri. It returns the CanvasBitmap so that it can be cached for efficiency.
        /// </summary>
        /// <param name="surfaceLock">The object to lock to prevent multiple threads
        /// from accessing the surface at the same time.</param>
        /// <param name="surface">CompositionDrawingSurface</param>
        /// <param name="uri">Uri of the image to be loaded onto the SurfaceImage.</param>
        /// <param name="options">Describes the image's resize and alignment options in the allocated space.</param>
        /// <param name="canvasBitmap">The CanvasBitmap on which the image is loaded.</param>
        /// <returns>CanvasBitmap</returns>
        public async Task <CanvasBitmap> RedrawSurfaceImageAsync(object surfaceLock, CompositionDrawingSurface surface,
                                                                 Uri uri, CompositionSurfaceImageOptions options, CanvasBitmap canvasBitmap)
        {
            if ((canvasBitmap == null) && (uri != null))
            {
                try
                {
                    canvasBitmap = await CanvasBitmap.LoadAsync(_canvasDevice, uri);
                }
                catch (IOException)
                {
                    // Do nothing here as RenderBitmap method will fill the surface
                    // with options.SurfaceBackgroundColor as the image failed to load
                    // from Uri
                }
            }

            // Render the image to the surface
            RenderBitmap(surfaceLock, surface, canvasBitmap, options);

            return(canvasBitmap);
        }
Esempio n. 8
0
        /// <summary>
        /// Renders the CanvasBitmap on the CompositionDrawingSurface based on the given options.
        /// </summary>
        /// <param name="surfaceLock">The object to lock to prevent multiple threads
        /// from accessing the surface at the same time.</param>
        /// <param name="surface">CompositionDrawingSurface on which the CanvasBitmap has to be rendered.</param>
        /// <param name="canvasBitmap">CanvasBitmap created by loading the image from the Uri</param>
        /// <param name="options">Describes the image's resize and alignment options in the allocated space.</param>
        private static void RenderBitmap(object surfaceLock, CompositionDrawingSurface surface, CanvasBitmap canvasBitmap,
                                         CompositionSurfaceImageOptions options)
        {
            var surfaceSize = surface.Size;

            // If the canvasBitmap is null, then just fill the surface with the SurfaceBackgroundColor
            if (canvasBitmap == null)
            {
                // No need to render if the width and/or height of the surface is zero
                if (surfaceSize.IsEmpty || surfaceSize.Width.IsZero() || surfaceSize.Height.IsZero())
                {
                    return;
                }

                //
                // Since multiple threads could be trying to get access to the device/surface
                // at the same time, we need to do any device/surface work under a lock.
                //
                lock (surfaceLock)
                {
                    using (var session = CanvasComposition.CreateDrawingSession(surface))
                    {
                        // Clear the surface with the SurfaceBackgroundColor
                        session.Clear(options.SurfaceBackgroundColor);
                    }

                    // No need to proceed further
                    return;
                }
            }

            //
            // Since multiple threads could be trying to get access to the device/surface
            // at the same time, we need to do any device/surface work under a lock.
            //
            lock (surfaceLock)
            {
                // Is AutoResize Enabled?
                if (options.AutoResize)
                {
                    // If AutoResize is allowed and the canvasBitmap size and surface size are
                    // not matching then resize the surface to match the canvasBitmap size.
                    //
                    // NOTE: HorizontalAlignment, Vertical Alignment and Stretch will be
                    // handled by the CompositionSurfaceBrush created using this surface.
                    //
                    if (canvasBitmap.Size != surfaceSize)
                    {
                        // Resize the surface
                        CanvasComposition.Resize(surface, canvasBitmap.Size);
                        surfaceSize = canvasBitmap.Size;
                    }

                    // No need to render if the width and/or height of the surface is zero
                    if (surfaceSize.IsEmpty || surface.Size.Width.IsZero() || surface.Size.Height.IsZero())
                    {
                        return;
                    }

                    // Draw the image to the surface
                    using (var session = CanvasComposition.CreateDrawingSession(surface))
                    {
                        // Render the image
                        session.DrawImage(canvasBitmap,                                                      // CanvasBitmap
                                          new Rect(0, 0, surfaceSize.Width, surfaceSize.Height),             // Target Rectangle
                                          new Rect(0, 0, canvasBitmap.Size.Width, canvasBitmap.Size.Height), // Source Rectangle
                                          options.Opacity,                                                   // Opacity
                                          options.Interpolation);                                            // Interpolation
                    }
                }
                else
                {
                    // No need to render if the width and/or height of the surface is zero
                    if (surfaceSize.IsEmpty || surface.Size.Width.IsZero() || surface.Size.Height.IsZero())
                    {
                        return;
                    }

                    var bitmapSize   = canvasBitmap.Size;
                    var sourceWidth  = bitmapSize.Width;
                    var sourceHeight = bitmapSize.Height;
                    var ratio        = sourceWidth / sourceHeight;
                    var targetWidth  = 0d;
                    var targetHeight = 0d;
                    var left         = 0d;
                    var top          = 0d;

                    // Stretch Mode
                    switch (options.Stretch)
                    {
                    case Stretch.None:
                        targetWidth  = sourceWidth;
                        targetHeight = sourceHeight;
                        break;

                    case Stretch.Fill:
                        targetWidth  = surfaceSize.Width;
                        targetHeight = surfaceSize.Height;
                        break;

                    case Stretch.Uniform:
                        // If width is greater than height
                        if (ratio > 1.0)
                        {
                            targetHeight = Math.Min(surfaceSize.Width / ratio, surfaceSize.Height);
                            targetWidth  = targetHeight * ratio;
                        }
                        else
                        {
                            targetWidth  = Math.Min(surfaceSize.Height * ratio, surfaceSize.Width);
                            targetHeight = targetWidth / ratio;
                        }
                        break;

                    case Stretch.UniformToFill:
                        // If width is greater than height
                        if (ratio > 1.0)
                        {
                            targetHeight = Math.Max(surfaceSize.Width / ratio, surfaceSize.Height);
                            targetWidth  = targetHeight * ratio;
                        }
                        else
                        {
                            targetWidth  = Math.Max(surfaceSize.Height * ratio, surfaceSize.Width);
                            targetHeight = targetWidth / ratio;
                        }
                        break;
                    }

                    // Horizontal Alignment
                    switch (options.HorizontalAlignment)
                    {
                    case AlignmentX.Left:
                        left = 0;
                        break;

                    case AlignmentX.Center:
                        left = (surfaceSize.Width - targetWidth) / 2.0;
                        break;

                    case AlignmentX.Right:
                        left = surfaceSize.Width - targetWidth;
                        break;
                    }

                    // Vertical Alignment
                    switch (options.VerticalAlignment)
                    {
                    case AlignmentY.Top:
                        top = 0;
                        break;

                    case AlignmentY.Center:
                        top = (surfaceSize.Height - targetHeight) / 2.0;
                        break;

                    case AlignmentY.Bottom:
                        top = surfaceSize.Height - targetHeight;
                        break;
                    }

                    // Draw the image to the surface
                    using (var session = CanvasComposition.CreateDrawingSession(surface))
                    {
                        // Clear the surface with the SurfaceBackgroundColor
                        session.Clear(options.SurfaceBackgroundColor);
                        // Render the image
                        session.DrawImage(canvasBitmap,                                   // CanvasBitmap
                                          new Rect(left, top, targetWidth, targetHeight), // Target Rectangle
                                          new Rect(0, 0, sourceWidth, sourceHeight),      // Source Rectangle
                                          options.Opacity,                                // Opacity
                                          options.Interpolation);                         // Interpolation
                    }
                }
            }
        }
Esempio n. 9
0
 /// <summary>
 /// Resizes the SurfaceImage to the given size and redraws the SurfaceImage
 /// by resizing the existing canvasBitmap
 /// </summary>
 /// <param name="surfaceLock">The object to lock to prevent multiple threads
 /// from accessing the surface at the same time.</param>
 /// <param name="surface">CompositionDrawingSurface</param>
 /// <param name="options">Describes the image's resize and alignment options in the allocated space.</param>
 /// <param name="canvasBitmap">The CanvasBitmap on which the image is loaded.</param>
 public void RedrawSurfaceImage(object surfaceLock, CompositionDrawingSurface surface,
                                CompositionSurfaceImageOptions options, CanvasBitmap canvasBitmap)
 {
     // Render the image to the surface
     RenderBitmap(surfaceLock, surface, canvasBitmap, options);
 }
Esempio n. 10
0
        /// <summary>
        /// Creates a CompositionSurfaceImage having the given size onto which an image (based on the Uri
        /// and the options) is loaded.
        /// </summary>
        /// <param name="uri">Uri of the image to be loaded onto the SurfaceImage.</param>
        /// <param name="size">New size of the SurfaceImage</param>
        /// <param name="options">Describes the image's resize and alignment options in the allocated space.</param>
        /// <returns>ICompositionSurfaceImage</returns>
        public async Task <ICompositionSurfaceImage> CreateSurfaceImageAsync(Uri uri, Size size, CompositionSurfaceImageOptions options)
        {
            // Initialize the SurfaceImage
            ICompositionSurfaceImage surfaceImage = new CompositionSurfaceImage(this, uri, size, options);

            // Render the image onto the surface
            await surfaceImage.RedrawAsync();

            return(surfaceImage);
        }