Skip to content

Commit

Permalink
Improved BorderEffect image stretching mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 committed Jul 13, 2017
1 parent efd152b commit b220026
Showing 1 changed file with 37 additions and 39 deletions.
76 changes: 37 additions & 39 deletions UICompositionAnimations/Behaviours/AcrylicEffectHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Windows.Foundation;
using Windows.Graphics.DirectX;
using Windows.Graphics.Effects;
using Windows.Graphics.Imaging;
using Windows.UI;
using Windows.UI.Composition;
using JetBrains.Annotations;
Expand All @@ -32,6 +33,40 @@ internal static class AcrylicEffectHelper
/// </summary>
private static readonly IDictionary<String, CompositionSurfaceBrush> SurfacesCache = new Dictionary<String, CompositionSurfaceBrush>();

/// <summary>
/// Loads a <see cref="CompositionSurfaceBrush"/> from the input <see cref="Uri"/>, and prepares it for the <see cref="BorderEffect"/>
/// </summary>
/// <param name="creator">The resource creator to use to load the image bitmap (it can be the same <see cref="CanvasDevice"/> used later)</param>
/// <param name="compositor">The compositor instance to use to create the final brush</param>
/// <param name="canvasDevice">The device to use to process the Win2D image</param>
/// <param name="uri">The path to the image to load</param>
private static async Task<CompositionSurfaceBrush> LoadSurfaceBrushAsync([NotNull] ICanvasResourceCreator creator,
[NotNull] Compositor compositor, [NotNull] CanvasDevice canvasDevice, [NotNull] Uri uri)
{
using (CanvasBitmap bitmap = await CanvasBitmap.LoadAsync(creator, uri))
{
// Get the device and the target surface
CompositionGraphicsDevice device = CanvasComposition.CreateCompositionGraphicsDevice(compositor, canvasDevice);
CompositionDrawingSurface surface = device.CreateDrawingSurface(default(Size),
DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied);

// Calculate the surface size
Size size = bitmap.Size;
CanvasComposition.Resize(surface, size);

// Draw the image on the surface and get the resulting brush
using (CanvasDrawingSession session = CanvasComposition.CreateDrawingSession(surface))
{
session.Clear(Color.FromArgb(0, 0, 0, 0));
session.DrawImage(bitmap, new Rect(0, 0, size.Width, size.Height), new Rect(0, 0, size.Width, size.Height));
session.EffectTileSize = new BitmapSize { Width = (uint)size.Width, Height = (uint)size.Height };
CompositionSurfaceBrush brush = surface.Compositor.CreateSurfaceBrush(surface);
brush.Stretch = CompositionStretch.None;
return brush;
}
}
}

/// <summary>
/// Loads a <see cref="CompositionSurfaceBrush"/> instance with the target image
/// </summary>
Expand All @@ -50,26 +85,7 @@ async Task<CompositionSurfaceBrush> LoadImageAsync(bool shouldThrow)
// Load the image - this will only succeed when there's an available Win2D device
try
{
using (CanvasBitmap bitmap = await CanvasBitmap.LoadAsync(canvas, uri))
{
// Get the device and the target surface
CompositionGraphicsDevice device = CanvasComposition.CreateCompositionGraphicsDevice(compositor, canvas.Device);
CompositionDrawingSurface surface = device.CreateDrawingSurface(default(Size),
DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied);

// Calculate the surface size
Size size = bitmap.Size;
CanvasComposition.Resize(surface, size);

// Draw the image on the surface and get the resulting brush
using (CanvasDrawingSession session = CanvasComposition.CreateDrawingSession(surface))
{
session.Clear(Color.FromArgb(0, 0, 0, 0));
session.DrawImage(bitmap, new Rect(0, 0, size.Width, size.Height), new Rect(0, 0, size.Width, size.Height));
CompositionSurfaceBrush brush = surface.Compositor.CreateSurfaceBrush(surface);
return brush;
}
}
return await LoadSurfaceBrushAsync(canvas, compositor, canvas.Device, uri);
}
catch when (!shouldThrow)
{
Expand Down Expand Up @@ -165,25 +181,7 @@ private static async Task<CompositionSurfaceBrush> LoadWin2DSurfaceBrushFromImag
{
// This will throw and the canvas will re-initialize the Win2D device if needed
CanvasDevice sharedDevice = CanvasDevice.GetSharedDevice();
using (CanvasBitmap bitmap = await CanvasBitmap.LoadAsync(sharedDevice, uri))
{
// Get the device and the target surface
CompositionGraphicsDevice device = CanvasComposition.CreateCompositionGraphicsDevice(compositor, sharedDevice);
CompositionDrawingSurface surface = device.CreateDrawingSurface(default(Size),
DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied);

// Calculate the surface size
Size size = bitmap.Size;
CanvasComposition.Resize(surface, size);

// Draw the image on the surface and get the resulting brush
using (CanvasDrawingSession session = CanvasComposition.CreateDrawingSession(surface))
{
session.Clear(Color.FromArgb(0, 0, 0, 0));
session.DrawImage(bitmap, new Rect(0, 0, size.Width, size.Height), new Rect(0, 0, size.Width, size.Height));
brush = surface.Compositor.CreateSurfaceBrush(surface);
}
}
brush = await LoadSurfaceBrushAsync(sharedDevice, compositor, sharedDevice, uri);
}
catch
{
Expand Down

0 comments on commit b220026

Please sign in to comment.