Created
April 6, 2016 22:31
-
-
Save robmikh/8c74f176349d31fd02f58a25b9508b9a to your computer and use it in GitHub Desktop.
Custom Image Control using Composition
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Robmikh.Util.CompositionImageLoader; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Windows.UI.Composition; | |
using Windows.UI.Xaml; | |
using Windows.UI.Xaml.Hosting; | |
namespace ControlSample.Helpers | |
{ | |
public static class CompositionHelper | |
{ | |
private static Compositor _compositor; | |
public static Compositor Compositor | |
{ | |
get | |
{ | |
if (_compositor == null) | |
{ | |
_compositor = ElementCompositionPreview.GetElementVisual(Window.Current.Content).Compositor; | |
} | |
return _compositor; | |
} | |
} | |
private static IImageLoader _imageLoader; | |
public static IImageLoader ImageLoader | |
{ | |
get | |
{ | |
if (_imageLoader == null) | |
{ | |
_imageLoader = ImageLoaderFactory.CreateImageLoader(Compositor); | |
} | |
return _imageLoader; | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using ControlSample.Helpers; | |
using Robmikh.Util.CompositionImageLoader; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Numerics; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Windows.UI.Composition; | |
using Windows.UI.Xaml; | |
using Windows.UI.Xaml.Controls; | |
using Windows.UI.Xaml.Hosting; | |
namespace ControlSample.Controls | |
{ | |
public class ImageVisual : UserControl | |
{ | |
private static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(Uri), typeof(ImageVisual), new PropertyMetadata(null, SourcePropertyChanged)); | |
private SpriteVisual _visual; | |
private IManagedSurface _surface; | |
private CompositionSurfaceBrush _imageBrush; | |
public SpriteVisual Visual | |
{ | |
get { return _visual; } | |
} | |
public CompositionSurfaceBrush ImageBrush | |
{ | |
get { return _imageBrush; } | |
} | |
public Uri Source | |
{ | |
get { return (Uri)GetValue(SourceProperty); } | |
set { SetValue(SourceProperty, value); } | |
} | |
public ImageVisual() | |
{ | |
InitComposition(); | |
SizeChanged += ImageVisual_SizeChanged; | |
} | |
private void ImageVisual_SizeChanged(object sender, Windows.UI.Xaml.SizeChangedEventArgs e) | |
{ | |
if (_visual != null) | |
{ | |
_visual.Size = new Vector2((float)ActualWidth, (float)ActualHeight); | |
} | |
} | |
private void InitComposition() | |
{ | |
var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor; | |
_visual = compositor.CreateSpriteVisual(); | |
_visual.Size = new Vector2((float)ActualWidth, (float)ActualHeight); | |
_surface = CompositionHelper.ImageLoader.CreateManagedSurfaceFromUri(Source); | |
_imageBrush = compositor.CreateSurfaceBrush(_surface.Surface); | |
_visual.Brush = _imageBrush; | |
ElementCompositionPreview.SetElementChildVisual(this, _visual); | |
} | |
private void UpdateImage(Uri newImageUri) | |
{ | |
if (_surface != null) | |
{ | |
var ignored = _surface.RedrawSurface(newImageUri); | |
} | |
} | |
private static void SourcePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) | |
{ | |
var control = obj as ImageVisual; | |
var oldUri = args.OldValue as Uri; | |
var newUri = args.NewValue as Uri; | |
if (control != null && !newUri.Equals(oldUri)) | |
{ | |
control.UpdateImage(newUri); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Page | |
x:Class="ControlSample.MainPage" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:local="using:ControlSample" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
xmlns:controls="using:ControlSample.Controls" | |
mc:Ignorable="d"> | |
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> | |
<controls:ImageVisual x:Name="ImageVisualControl" Width="480" Height="176.5" Source="http://ncmedia.azureedge.net/ncmedia/2014/10/MSFT_logo_rgb_C-Gray.png" /> | |
<Button HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0, 0, 10, 10" Content="Invert Image" Click="Button_Click" /> | |
</Grid> | |
</Page> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Graphics.Canvas.Effects; | |
using Robmikh.Util.CompositionImageLoader; | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Numerics; | |
using System.Runtime.InteropServices.WindowsRuntime; | |
using Windows.Foundation; | |
using Windows.Foundation.Collections; | |
using Windows.Graphics.Effects; | |
using Windows.UI.Composition; | |
using Windows.UI.Xaml; | |
using Windows.UI.Xaml.Controls; | |
using Windows.UI.Xaml.Controls.Primitives; | |
using Windows.UI.Xaml.Data; | |
using Windows.UI.Xaml.Hosting; | |
using Windows.UI.Xaml.Input; | |
using Windows.UI.Xaml.Media; | |
using Windows.UI.Xaml.Navigation; | |
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 | |
namespace ControlSample | |
{ | |
/// <summary> | |
/// An empty page that can be used on its own or navigated to within a Frame. | |
/// </summary> | |
public sealed partial class MainPage : Page | |
{ | |
public MainPage() | |
{ | |
this.InitializeComponent(); | |
} | |
private void Button_Click(object sender, RoutedEventArgs e) | |
{ | |
var visual = ImageVisualControl.Visual; | |
var imageBrush = ImageVisualControl.ImageBrush; | |
var currentBrush = visual.Brush; | |
var compositor = visual.Compositor; | |
if (currentBrush is CompositionSurfaceBrush) | |
{ | |
IGraphicsEffect graphicsEffect = new InvertEffect | |
{ | |
Name = "invertEffect", | |
Source = new CompositionEffectSourceParameter("image") | |
}; | |
var effectFactory = compositor.CreateEffectFactory(graphicsEffect); | |
var effectBrush = effectFactory.CreateBrush(); | |
effectBrush.SetSourceParameter("image", imageBrush); | |
visual.Brush = effectBrush; | |
} | |
else if (currentBrush is CompositionEffectBrush) | |
{ | |
visual.Brush = imageBrush; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment