コード例 #1
0
        /// <summary>
        /// Creates an instance of CompositionEffectFactory.
        /// </summary>
        /// <param name="compositor">Compositor</param>
        /// <param name="graphicsEffect">The type of effect to create.</param>
        /// <param name="animatablePropertyExpressions">List of Expression each specifying
        /// an animatable property</param>
        /// <returns>The created CompositionEffectFactory object.</returns>
        public static CompositionEffectFactory CreateEffectFactory(this Compositor compositor,
                                                                   IGraphicsEffect graphicsEffect, params Expression <Func <object> >[] animatablePropertyExpressions)
        {
            var animatableProperties = animatablePropertyExpressions.Select(CompositionExpressionEngine.ParseExpression).ToArray();

            return(compositor.CreateEffectFactory(graphicsEffect, animatableProperties));
        }
コード例 #2
0
        public void ReflectOverAllEffects()
        {
            var assembly = typeof(GaussianBlurEffect).GetTypeInfo().Assembly;

            var effectTypes = from type in assembly.DefinedTypes
                              where type.ImplementedInterfaces.Contains(typeof(IGraphicsEffect))
                              where type.AsType() != typeof(PixelShaderEffect)
                              select type;

            var device  = new CanvasDevice();
            var device2 = new CanvasDevice();

            foreach (var effectType in effectTypes)
            {
                IGraphicsEffect effect = (IGraphicsEffect)Activator.CreateInstance(effectType.AsType());

                // Test an un-realized effect instance.
                TestEffectSources(effectType, effect, null);
                TestEffectProperties(effectType, effect);

                // Realize the effect (creating a backing D2D effect instance), then test it again.
                var initialSourceImage = RealizeEffect(device, effectType, effect);

                TestEffectSources(effectType, effect, initialSourceImage);
                TestEffectProperties(effectType, effect);

                // Test that interop can successfully transfer property values in both directions.
                TestEffectInterop(device, device2, effectType, effect);
            }
        }
コード例 #3
0
        static void TestEffectInterop(CanvasDevice device, CanvasDevice device2, TypeInfo effectType, IGraphicsEffect realizedEffect)
        {
            // One Win2D effect is backed by a realized ID2D1Effect instance, the other is not.
            // Their property values should be the same either way.
            IGraphicsEffect unrealizedEffect = (IGraphicsEffect)Activator.CreateInstance(effectType.AsType());

            PropertyValuesShouldMatch(effectType, realizedEffect, unrealizedEffect);

            // Create a new ID2D1Effect instance, then wrap a Win2D effect around it.
            // We should get the same default property values either way.
            IGraphicsEffect wrappedEffect = EffectAccessor.CreateThenWrapNewEffectOfSameType(device, realizedEffect);

            // Special case: Win2D intentionally defaults to a different DpiCompensationEffect.BorderMode vs. D2D.
            if (wrappedEffect is DpiCompensationEffect)
            {
                var dpiCompensationEffect = wrappedEffect as DpiCompensationEffect;
                Assert.AreEqual(EffectBorderMode.Soft, dpiCompensationEffect.BorderMode);
                dpiCompensationEffect.BorderMode = EffectBorderMode.Hard;
            }

            PropertyValuesShouldMatch(effectType, unrealizedEffect, wrappedEffect);

            // Re-realize the new effect onto a second device.
            // All property values should be successfully transferred across.
            RealizeEffect(device2, effectType, wrappedEffect);

            PropertyValuesShouldMatch(effectType, unrealizedEffect, wrappedEffect);
        }
コード例 #4
0
        private static void GetActiveEffects(IGraphicsEffectSource effectSource, List <Type> typesSeen)
        {
            // Record this node if it is an IGraphicsEffect.
            IGraphicsEffect effect = effectSource as IGraphicsEffect;

            if (effect != null)
            {
                typesSeen.Add(effect.GetType());

                foreach (var property in effect.GetType().GetRuntimeProperties())
                {
                    if (property.PropertyType == typeof(IGraphicsEffectSource))
                    {
                        // Recurse into any source properties that could themselves be effects.
                        var source = (IGraphicsEffectSource)property.GetValue(effect);

                        GetActiveEffects(source, typesSeen);
                    }
                    else if (property.PropertyType == typeof(IList <IGraphicsEffectSource>))
                    {
                        // Recurse into any array source properties.
                        var sources = (IList <IGraphicsEffectSource>)property.GetValue(effect);

                        foreach (var source in sources)
                        {
                            GetActiveEffects(source, typesSeen);
                        }
                    }
                }
            }
        }
コード例 #5
0
        private async void ViewEffectGraph_Click(object sender, RoutedEventArgs e)
        {
            if (!_inDialog)
            {
                _inDialog = true;

                IGraphicsEffect effect = Material.Effect;

                if (effect != null)
                {
                    StringBuilder sb = new StringBuilder(1024);

                    EffectToString(sb, 0, effect, (CompositionEffectBrush)Material.Brush);

                    ViewEffectDialog viewEffectDialog = new ViewEffectDialog()
                    {
                        Title                      = "View Effect Graph",
                        PrimaryButtonText          = "OK",
                        HorizontalContentAlignment = HorizontalAlignment.Center,
                        IsSecondaryButtonEnabled   = false,
                    };

                    viewEffectDialog.EffectText = sb.ToString();

                    await viewEffectDialog.ShowAsync();
                }

                _inDialog = false;
            }
        }
コード例 #6
0
        public static async Task <AttachedAnimatableCompositionEffect <T> > AttachCompositionAnimatableInAppCustomAcrylicEffectAsync <TSource, T>(
            [NotNull] this TSource element, [NotNull] T target,
            float on, float off, bool initiallyVisible,
            Color color, float colorMix, [CanBeNull] CanvasControl canvas, [NotNull] Uri uri,
            int timeThreshold = 1000, bool reload = false, bool disposeOnUnload = false)
            where TSource : FrameworkElement
            where T : FrameworkElement
        {
            // Get the compositor
            Visual visual = await DispatcherHelper.GetFromUIThreadAsync(element.GetVisual);

            Compositor compositor = visual.Compositor;

            // Create the blur effect and the effect factory
            CompositionBackdropBrush backdropBrush = compositor.CreateBackdropBrush();
            GaussianBlurEffect       blurEffect    = new GaussianBlurEffect
            {
                Name         = "Blur",
                BlurAmount   = 0f,
                BorderMode   = EffectBorderMode.Hard,
                Optimization = EffectOptimization.Balanced,
                Source       = new CompositionEffectSourceParameter(nameof(backdropBrush))
            };
            const String animationPropertyName = "Blur.BlurAmount";

            // Prepare the dictionary with the parameters to add
            IDictionary <String, CompositionBrush> sourceParameters = new Dictionary <String, CompositionBrush>
            {
                { nameof(backdropBrush), backdropBrush }
            };

            // Get the noise brush using Win2D
            IGraphicsEffect source = await AcrylicEffectHelper.ConcatenateEffectWithTintAndBorderAsync(compositor,
                                                                                                       blurEffect, sourceParameters, color, colorMix, canvas, uri, timeThreshold, reload);

            // Make sure the Win2D brush was loaded correctly
            CompositionEffectFactory effectFactory = compositor.CreateEffectFactory(source, new[] { animationPropertyName });

            // Create the effect factory and apply the final effect
            CompositionEffectBrush effectBrush = effectFactory.CreateBrush();

            foreach (KeyValuePair <String, CompositionBrush> pair in sourceParameters)
            {
                effectBrush.SetSourceParameter(pair.Key, pair.Value);
            }

            // Assign the effect to a brush and display it
            SpriteVisual sprite = compositor.CreateSpriteVisual();

            sprite.Brush = effectBrush;
            await AddToTreeAndBindSizeAsync(target.GetVisual(), target, sprite);

            if (initiallyVisible)
            {
                await DispatcherHelper.RunOnUIThreadAsync(() => element.Opacity = 1);
            }
            return(new AttachedAnimatableCompositionEffect <T>(target, sprite, new CompositionAnimationParameters(animationPropertyName, on, off), disposeOnUnload));
        }
コード例 #7
0
ファイル: EffectTests.cs プロジェクト: gkrishnaa/Win2D
        static void TestEffectProperties(TypeInfo effectType, IGraphicsEffect effect)
        {
            var properties = (from property in effectType.DeclaredProperties
                              where property.Name != "Name"
                              where property.Name != "Sources"
                              where property.PropertyType != typeof(IGraphicsEffectSource)
                              select property).ToList();

            IList <object> effectProperties = new ViewIndexerAsList <object>(() => EffectAccessor.GetPropertyCount(effect),
                                                                             i => EffectAccessor.GetProperty(effect, i));

            FilterOutCustomizedEffectProperties(effectType.AsType(), ref properties, ref effectProperties);

            // Should have the same number of strongly typed properties as elements in the properties collection.
            Assert.AreEqual(properties.Count, effectProperties.Count);

            // Store the initial property values.
            var initialValues = effectProperties.ToList();

            var whichIndexIsProperty = new List <int>();

            // Changing strongly typed properties should change the properties collection.
            for (int i = 0; i < effectProperties.Count; i++)
            {
                object testValue1 = GetArbitraryTestValue(properties[i].PropertyType, true);
                object testValue2 = GetArbitraryTestValue(properties[i].PropertyType, false);

                // Change a property value, and see which collection properties match the result.
                properties[i].SetValue(effect, testValue1);

                var matches1 = (from j in Enumerable.Range(0, effectProperties.Count)
                                where BoxedValuesAreEqual(effectProperties[j], Box(testValue1, properties[i]), properties[i])
                                select j).ToList();

                // Change the same property to a different value, and see which collection properties match now.
                properties[i].SetValue(effect, testValue2);

                var matches2 = (from j in Enumerable.Range(0, effectProperties.Count)
                                where BoxedValuesAreEqual(effectProperties[j], Box(testValue2, properties[i]), properties[i])
                                select j).ToList();

                // There should be one and only one property that matched both times. If not,
                // either we don't have 1 <-> 1 mapping between strongly typed properties and
                // collection indices, or something went wrong during the boxing type conversions.
                var intersection = matches1.Intersect(matches2);
                Assert.AreEqual(1, intersection.Count());
                int whichIndexIsThis = intersection.Single();
                whichIndexIsProperty.Add(whichIndexIsThis);

                // Change the property value back to its initial state.
                properties[i].SetValue(effect, Unbox(initialValues[whichIndexIsThis], properties[i]));
                Assert.IsTrue(BoxedValuesAreEqual(initialValues[whichIndexIsThis], effectProperties[whichIndexIsThis], properties[i]));
            }

            // Should not have any duplicate property mappings.
            Assert.AreEqual(whichIndexIsProperty.Count, whichIndexIsProperty.Distinct().Count());
        }
コード例 #8
0
        public Form1() : base()
        {
            InitializeComponent();

            // Get graphics device.
            canvasDevice = CanvasDevice.GetSharedDevice();

            // Create effect graph.
            acrylicEffect = CreateAcrylicEffectGraph();
        }
コード例 #9
0
        static void PropertyValuesShouldMatch(TypeInfo effectType, IGraphicsEffect effect1, IGraphicsEffect effect2)
        {
            foreach (var property in GetEffectProperties(effectType))
            {
                object value1 = property.GetValue(effect1);
                object value2 = property.GetValue(effect2);

                AssertPropertyValuesAreEqual(value1, value2);
            }
        }
コード例 #10
0
        public void LinkLayerEffects(Layer nextLayer)
        {
            IGraphicsEffect source = _inputEffect;

            _chainedEffect = null;

            // Link the effect chain
            foreach (var effect in Effects)
            {
                if (effect.Enabled)
                {
                    effect.GraphicsEffect.GetType().GetProperties().FirstOrDefault(x => x.Name == "Source").SetValue(effect.GraphicsEffect, source);
                    source         = effect.GraphicsEffect;
                    _chainedEffect = effect.GraphicsEffect;
                }
            }

            if (nextLayer != null)
            {
                IGraphicsEffect layerEffect = EffectRoot;
                IGraphicsEffect blendEffect;

                blendEffect = Helpers.GetEffectFromBlendMode(_blendMode);

                if (blendEffect is BlendEffect)
                {
                    BlendEffect blend = (BlendEffect)blendEffect;
                    blend.Foreground = nextLayer.GenerateEffectGraph(false);
                    blend.Background = layerEffect;
                    _blendEffect     = blend;
                }
                else if (blendEffect is CompositeEffect)
                {
                    CompositeEffect composite = (CompositeEffect)blendEffect;
                    composite.Sources.Add(nextLayer.GenerateEffectGraph(false));
                    composite.Sources.Add(layerEffect);
                    _blendEffect = composite;
                }
                else if (blendEffect is ArithmeticCompositeEffect)
                {
                    ArithmeticCompositeEffect arith = (ArithmeticCompositeEffect)blendEffect;
                    arith.Source1 = layerEffect;
                    arith.Source2 = nextLayer.GenerateEffectGraph(false);
                    _blendEffect  = arith;
                }
                else
                {
                    Debug.Assert(false);
                }
            }
            else
            {
                _blendEffect = null;
            }
        }
コード例 #11
0
        static void TestEffectSources(TypeInfo effectType, IGraphicsEffect effect)
        {
            var sourceProperties = (from property in effectType.DeclaredProperties
                                    where property.PropertyType == typeof(IGraphicsEffectSource)
                                    select property).ToList();

            // Should have the same number of strongly typed properties as the effect has sources.
            Assert.AreEqual(sourceProperties.Count, EffectAccessor.GetSourceCount(effect));

            // Initial source values should all be null.
            for (int i = 0; i < EffectAccessor.GetSourceCount(effect); i++)
            {
                Assert.IsNull(EffectAccessor.GetSource(effect, i));
                Assert.IsNull(sourceProperties[i].GetValue(effect));
            }

            var testValue1 = new GaussianBlurEffect();
            var testValue2 = new ShadowEffect();

            var whichIndexIsProperty = new List <int>();

            // Changing strongly typed properties should change the sources reported by IGraphicsEffectD2D1Interop.
            for (int i = 0; i < EffectAccessor.GetSourceCount(effect); i++)
            {
                // Change a property value, and see which source changes.
                sourceProperties[i].SetValue(effect, testValue1);

                int whichIndexIsThis = 0;

                while (EffectAccessor.GetSource(effect, whichIndexIsThis) != testValue1)
                {
                    whichIndexIsThis++;
                    Assert.IsTrue(whichIndexIsThis < EffectAccessor.GetSourceCount(effect));
                }

                whichIndexIsProperty.Add(whichIndexIsThis);

                // Change the same property value again, and make sure the same source changes.
                sourceProperties[i].SetValue(effect, testValue2);
                Assert.AreSame(testValue2, EffectAccessor.GetSource(effect, whichIndexIsThis));

                // Change the property value to null.
                sourceProperties[i].SetValue(effect, null);
                Assert.IsNull(EffectAccessor.GetSource(effect, whichIndexIsThis));
            }

            // Should not have any duplicate property mappings.
            Assert.AreEqual(whichIndexIsProperty.Count, whichIndexIsProperty.Distinct().Count());
        }
コード例 #12
0
        public void ReflectOverAllEffects()
        {
            var assembly = typeof(GaussianBlurEffect).GetTypeInfo().Assembly;

            var effectTypes = from type in assembly.DefinedTypes
                              where type.ImplementedInterfaces.Contains(typeof(IGraphicsEffect))
                              select type;

            foreach (var effectType in effectTypes)
            {
                IGraphicsEffect effect = (IGraphicsEffect)Activator.CreateInstance(effectType.AsType());

                TestEffectSources(effectType, effect);
                TestEffectProperties(effectType, effect);
            }
        }
コード例 #13
0
        private void OnLayerChanged(object sender, string property)
        {
            try
            {
                IGraphicsEffect          effectGraph   = Layer.GenerateEffectGraph(true);
                CompositionEffectFactory effectFactory = _previewSprite.Compositor.CreateEffectFactory(effectGraph, null);
                _previewSprite.Brush = effectFactory.CreateBrush();
                Layer.UpdateResourceBindings((CompositionEffectBrush)_previewSprite.Brush);
            }
            catch
            {
                _previewSprite.Brush = null;
            }

            LayerDescription.Text = Layer.Description;
        }
コード例 #14
0
        private async void UpdateBrush()
        {
            if (_layerInvalidated)
            {
                // Clear the old brush
                _effectBrush = null;

                IGraphicsEffect effecGraph = _groupLayer.GenerateEffectGraph(false);
                if (effecGraph != null)
                {
                    try
                    {
                        CompositionEffectFactory effectFactory = _compositor.CreateEffectFactory(effecGraph, null);
                        _effectBrush = effectFactory.CreateBrush();

                        foreach (Layer layer in _groupLayer.Layers)
                        {
                            if (layer.Enabled)
                            {
                                layer.UpdateResourceBindings(_effectBrush);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        ContentDialog dialog = new ContentDialog()
                        {
                            Title                    = "Failed to create effect",
                            Content                  = String.Format("The effect creation failed with the following error.  Please simplify your material.\r\n\r\n\"{0}\"", e.Message.ToString().Replace("\r\n", " ")),
                            PrimaryButtonText        = "OK",
                            IsSecondaryButtonEnabled = false,
                        };

                        await dialog.ShowAsync();

                        // Clear out the old effect
                        _effectBrush = null;
                    }

                    // Clear the flag
                    _layerInvalidated = false;
                }

                _brushChangedHandler(this);
            }
        }
コード例 #15
0
        public CompositionHostControl()
        {
            InitializeComponent();

            // 手动高亮,下面代码用于创建 Win2d 的渲染设备
            _canvasDevice = CanvasDevice.GetSharedDevice();

            // Create host and attach root container for hosted tree.
            _compositionHost             = new CompositionHost();
            CompositionHostElement.Child = _compositionHost;
            _compositionHost.RegisterForDispose(this);

            _compositor      = _compositionHost.Compositor;
            _containerVisual = _compositor.CreateContainerVisual();

            // Create effect graph.
            _acrylicEffect = CreateAcrylicEffectGraph();
        }
コード例 #16
0
        public CompositionEffectBrush CreateEffectBrush(
            EffectType effectType,
            string effectName,
            float propertyValue,
            IEnumerable <string> properties)
        {
            IGraphicsEffect effectDesc = null;

            switch (effectType)
            {
            case EffectType.Saturation:
                effectDesc = new SaturationEffect()
                {
                    Name       = effectName,
                    Saturation = propertyValue,
                    Source     = new CompositionEffectSourceParameter("source")
                };
                break;

            case EffectType.HueRotation:
                effectDesc = new HueRotationEffect()
                {
                    Name   = effectName,
                    Angle  = propertyValue,
                    Source = new CompositionEffectSourceParameter("source")
                };
                break;

            case EffectType.Sepia:
                effectDesc = new SepiaEffect()
                {
                    Name      = effectName,
                    Intensity = propertyValue,
                    Source    = new CompositionEffectSourceParameter("source")
                };
                break;
            }

            CompositionEffectFactory effectFactory = _compositor.CreateEffectFactory(effectDesc, properties);
            CompositionEffectBrush   effectBrush   = effectFactory.CreateBrush();

            return(effectBrush);
        }
コード例 #17
0
        protected T StartEffectAnimation <T>(
            FrameworkElement element,
            IGraphicsEffect effect,
            Func <double, T> animationSetupFunc,
            Action <CompositionEffectBrush> brushSetupAction)
            where T : KeyFrameAnimation
        {
            var duration = Initialize(element);

            // Call a Func that will be used to setup the animation and create the keyframes, delay, etc.
            var animation     = animationSetupFunc(duration);
            var effectFactory = Window.Current.Compositor.CreateEffectFactory(effect, new[] { TargetProperty });
            var brush         = effectFactory.CreateBrush();

            // Call an Action that will be used to setup the CompositionEffectBrush object
            brushSetupAction(brush);

            brush.StartAnimation(TargetProperty, animation);

            return(animation);
        }
コード例 #18
0
        static ICanvasImage RealizeEffect(CanvasDevice device, TypeInfo effectType, IGraphicsEffect effect)
        {
            var dummySourceImage = new CanvasCommandList(device);

            // We can't realize an effect with invalid inputs, so must first set them all to something reasonable.
            foreach (var sourceProperty in effectType.DeclaredProperties.Where(p => p.PropertyType == typeof(IGraphicsEffectSource)))
            {
                sourceProperty.SetValue(effect, dummySourceImage);
            }

            // Add one image to any variable size Sources collection properties.
            foreach (var sourcesProperty in effectType.DeclaredProperties.Where(p => p.Name == "Sources"))
            {
                var sources = sourcesProperty.GetValue(effect) as IList <IGraphicsEffectSource>;

                sources.Clear();
                sources.Add(dummySourceImage);
            }

            EffectAccessor.RealizeEffect(device, effect);

            return(dummySourceImage);
        }
コード例 #19
0
        private void InitializeBrush(IGraphicsEffect effect, String uri)
        {
            Brush = Compositor.CreateEffectFactory(effect,
               new[]
               {
                    "effect.Source1Amount",
                    "effect.Source2Amount",
               }
           ).CreateBrush();

            SetForeground(uri);
        }
コード例 #20
0
        public static async Task <AttachedStaticCompositionEffect <T> > AttachCompositionCustomAcrylicEffectAsync <T>(
            [NotNull] this T element, Color color, float colorMix,
            [CanBeNull] CanvasControl canvas, [NotNull] Uri uri, int timeThreshold = 1000, bool reload = false, bool disposeOnUnload = false)
            where T : FrameworkElement
        {
            // Percentage check
            if (colorMix <= 0 || colorMix >= 1)
            {
                throw new ArgumentOutOfRangeException("The mix factors must be in the [0,1] range");
            }
            if (timeThreshold <= 0)
            {
                throw new ArgumentOutOfRangeException("The time threshold must be a positive number");
            }

            // Setup the compositor
            Visual     visual     = ElementCompositionPreview.GetElementVisual(element);
            Compositor compositor = visual.Compositor;

            // Prepare a luminosity to alpha effect to adjust the background contrast
            CompositionBackdropBrush         hostBackdropBrush   = compositor.CreateHostBackdropBrush();
            CompositionEffectSourceParameter backgroundParameter = new CompositionEffectSourceParameter(nameof(hostBackdropBrush));
            LuminanceToAlphaEffect           alphaEffect         = new LuminanceToAlphaEffect {
                Source = backgroundParameter
            };
            OpacityEffect opacityEffect = new OpacityEffect
            {
                Source  = alphaEffect,
                Opacity = 0.4f // Reduce the amount of the effect to avoid making bright areas completely black
            };

            // Layer [0,1,3] - Desktop background with blur and tint overlay
            BlendEffect alphaBlend = new BlendEffect
            {
                Background = backgroundParameter,
                Foreground = opacityEffect,
                Mode       = BlendEffectMode.Overlay
            };
            IDictionary <String, CompositionBrush> sourceParameters = new Dictionary <String, CompositionBrush>
            {
                { nameof(hostBackdropBrush), hostBackdropBrush }
            };

            // Get the noise brush using Win2D
            IGraphicsEffect source = await AcrylicEffectHelper.ConcatenateEffectWithTintAndBorderAsync(compositor,
                                                                                                       alphaBlend, sourceParameters, color, colorMix, canvas, uri, timeThreshold, reload);

            // Make sure the Win2D brush was loaded correctly
            CompositionEffectFactory factory = compositor.CreateEffectFactory(source);

            // Create the effect factory and apply the final effect
            CompositionEffectBrush effectBrush = factory.CreateBrush();

            foreach (KeyValuePair <String, CompositionBrush> pair in sourceParameters)
            {
                effectBrush.SetSourceParameter(pair.Key, pair.Value);
            }

            // Create the sprite to display and add it to the visual tree
            SpriteVisual sprite = compositor.CreateSpriteVisual();

            sprite.Brush = effectBrush;
            await AddToTreeAndBindSizeAsync(visual, element, sprite);

            return(new AttachedStaticCompositionEffect <T>(element, sprite, disposeOnUnload));
        }
コード例 #21
0
        public static async Task <AttachedStaticCompositionEffect <T> > AttachCompositionInAppCustomAcrylicEffectAsync <TSource, T>(
            [NotNull] this TSource element, [NotNull] T target, float blur, int ms, Color color, float colorMix, float?saturation,
            [CanBeNull] CanvasControl canvas, [NotNull] Uri uri, int timeThreshold = 1000, bool reload = false, bool fadeIn = false, bool disposeOnUnload = false)
            where TSource : FrameworkElement
            where T : FrameworkElement
        {
            // Percentage check
            if (saturation < 0 || saturation > 1)
            {
                throw new ArgumentOutOfRangeException("The input saturation value must be in the [0,1] range");
            }
            if (colorMix <= 0 || colorMix >= 1)
            {
                throw new ArgumentOutOfRangeException("The mix factors must be in the [0,1] range");
            }
            if (timeThreshold <= 0)
            {
                throw new ArgumentOutOfRangeException("The time threshold must be a positive number");
            }

            // Setup the compositor
            Visual     visual     = ElementCompositionPreview.GetElementVisual(element);
            Compositor compositor = visual.Compositor;

            // Prepare a luminosity to alpha effect to adjust the background contrast
            CompositionBackdropBrush backdropBrush = compositor.CreateBackdropBrush();
            const String
                blurName                  = "Blur",
                blurParameterName         = "Blur.BlurAmount";
            GaussianBlurEffect blurEffect = new GaussianBlurEffect
            {
                Name         = blurName,
                BlurAmount   = 0f,
                BorderMode   = EffectBorderMode.Hard,
                Optimization = EffectOptimization.Balanced,
                Source       = new CompositionEffectSourceParameter(nameof(backdropBrush))
            };

            // Background with blur and tint overlay
            IDictionary <String, CompositionBrush> sourceParameters = new Dictionary <String, CompositionBrush>
            {
                { nameof(backdropBrush), backdropBrush }
            };

            // Get the noise brush using Win2D
            IGraphicsEffect source = await AcrylicEffectHelper.ConcatenateEffectWithTintAndBorderAsync(compositor,
                                                                                                       blurEffect, sourceParameters, color, colorMix, canvas, uri, timeThreshold, reload);

            // Add the final saturation effect if needed
            if (saturation != null)
            {
                SaturationEffect saturationEffect = new SaturationEffect
                {
                    Saturation = saturation.Value,
                    Source     = source
                };
                source = saturationEffect;
            }

            // Make sure the Win2D brush was loaded correctly
            CompositionEffectFactory factory = compositor.CreateEffectFactory(source, new[] { blurParameterName });

            // Create the effect factory and apply the final effect
            CompositionEffectBrush effectBrush = factory.CreateBrush();

            foreach (KeyValuePair <String, CompositionBrush> pair in sourceParameters)
            {
                effectBrush.SetSourceParameter(pair.Key, pair.Value);
            }

            // Create the sprite to display and add it to the visual tree
            SpriteVisual sprite = compositor.CreateSpriteVisual();

            sprite.Brush = effectBrush;

            // Assign the visual
            if (fadeIn)
            {
                sprite.StopAnimation("Opacity");
                sprite.Opacity = 0;
            }
            await AddToTreeAndBindSizeAsync(target.GetVisual(), target, sprite);

            if (fadeIn)
            {
                // Fade the effect in
                ScalarKeyFrameAnimation opacityAnimation = sprite.Compositor.CreateScalarKeyFrameAnimation(1, 0,
                                                                                                           TimeSpan.FromMilliseconds(ms), null, sprite.GetEasingFunction(EasingFunctionNames.Linear));
                sprite.StartAnimation("Opacity", opacityAnimation);
            }

            // Animate the blur and return the result
            effectBrush.StartAnimationAsync(blurParameterName, blur, TimeSpan.FromMilliseconds(ms)).Forget();
            return(new AttachedStaticCompositionEffect <T>(target, sprite, disposeOnUnload));
        }
コード例 #22
0
 public SaturationEffect(IGraphicsEffect source) : base(source)
 {
 }
コード例 #23
0
        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            // Initialize Composition UI infrastructure.
            _leftRoot   = LeftContainer.GetVisual();
            _middleRoot = MiddleContainer.GetVisual();
            _rightRoot  = RightContainer.GetVisual();
            _compositor = _leftRoot.Compositor;

            _imageFactory = CompositionImageFactory.CreateCompositionImageFactory(_compositor);

            // Hook the sprite visuals into the XAML visual tree.
            _leftSpriteVisual = _compositor.CreateSpriteVisual();
            var side = (float)Math.Min(LeftPresenter.ActualWidth, LeftPresenter.ActualHeight);

            _leftSpriteVisual.Size = new Vector2(side, side);
            _leftRoot.Children.InsertAtTop(_leftSpriteVisual);
            _middleSpriteVisual = _compositor.CreateSpriteVisual();
            side = (float)Math.Min(MiddlePresenter.ActualWidth, MiddlePresenter.ActualHeight);
            _middleSpriteVisual.Size = new Vector2(side, side);
            _middleRoot.Children.InsertAtTop(_middleSpriteVisual);
            _rightSpriteVisual = _compositor.CreateSpriteVisual();
            side = (float)Math.Min(RightPresenter.ActualWidth, RightPresenter.ActualHeight);
            _rightSpriteVisual.Size = new Vector2(side, side);
            _rightRoot.Children.InsertAtTop(_rightSpriteVisual);

            // Create CompositionSurfaceBrush
            _imageBrush = _compositor.CreateSurfaceBrush();

            // Create an image source to load
            var imageSource = _imageFactory.CreateImageFromUri(new Uri("ms-appx:///Assets/flowers.jpg"));

            _imageBrush.Surface = imageSource.Surface;

            // Create and apply the first effect.
            _firstEffect = new SaturationEffect
            {
                Name   = "firstEffect",
                Source = new CompositionEffectSourceParameter("source")
            };
            var firstEffectFactory = _compositor.CreateEffectFactory(_firstEffect, new[] { "firstEffect.Saturation" });

            _effectBrush1           = firstEffectFactory.CreateBrush();
            _leftSpriteVisual.Brush = _effectBrush1;

            // Create and apply the second effect.
            var secondEffect = new InvertEffect
            {
                Name   = "secondEffect",
                Source = new CompositionEffectSourceParameter("source")
            };
            var secondEffectFactory = _compositor.CreateEffectFactory(secondEffect);

            _effectBrush2             = secondEffectFactory.CreateBrush();
            _middleSpriteVisual.Brush = _effectBrush2;

            // Create and apply the combined effect.
            _combinedEffect = new InvertEffect
            {
                Name   = "chained",
                Source = _firstEffect
            };
            var combinedEffectFactory = _compositor.CreateEffectFactory(_combinedEffect, new[] { "firstEffect.Saturation" });

            _combinedBrush           = combinedEffectFactory.CreateBrush();
            _rightSpriteVisual.Brush = _combinedBrush;

            // Chain the brushes
            _effectBrush1.SetSourceParameter("source", _imageBrush);
            _effectBrush2.SetSourceParameter("source", _imageBrush);
            _combinedBrush.SetSourceParameter("source", _imageBrush);
        }
コード例 #24
0
        static void TestEffectProperties(TypeInfo effectType, IGraphicsEffect effect)
        {
            var properties = GetEffectProperties(effectType).ToList();

            IList <object> effectProperties = new ViewIndexerAsList <object>(() => EffectAccessor.GetPropertyCount(effect),
                                                                             i => EffectAccessor.GetProperty(effect, i));

            FilterOutCustomizedEffectProperties(effectType.AsType(), ref properties, ref effectProperties);

            // Should have the same number of strongly typed properties as elements in the properties collection.
            Assert.AreEqual(properties.Count, effectProperties.Count);

            // Store the initial property values.
            var initialValues = effectProperties.ToList();

            var whichIndexIsProperty = new List <int>();

            // Changing strongly typed properties should change the properties collection.
            for (int i = 0; i < effectProperties.Count; i++)
            {
                object testValue1 = GetArbitraryTestValue(properties[i].PropertyType, true);
                object testValue2 = GetArbitraryTestValue(properties[i].PropertyType, false);

                // Change a property value, and see which collection properties match the result.
                properties[i].SetValue(effect, testValue1);
                AssertPropertyValuesAreEqual(testValue1, properties[i].GetValue(effect));

                var matches1 = (from j in Enumerable.Range(0, effectProperties.Count)
                                where BoxedValuesAreEqual(effectProperties[j], Box(testValue1, properties[i]), properties[i])
                                select j).ToList();

                // Change the same property to a different value, and see which collection properties match now.
                properties[i].SetValue(effect, testValue2);
                AssertPropertyValuesAreEqual(testValue2, properties[i].GetValue(effect));

                var matches2 = (from j in Enumerable.Range(0, effectProperties.Count)
                                where BoxedValuesAreEqual(effectProperties[j], Box(testValue2, properties[i]), properties[i])
                                select j).ToList();

                // There should be one and only one property that matched both times. If not,
                // either we don't have 1 <-> 1 mapping between strongly typed properties and
                // collection indices, or something went wrong during the boxing type conversions.
                var intersection = matches1.Intersect(matches2);
                Assert.AreEqual(1, intersection.Count());
                int whichIndexIsThis = intersection.Single();
                whichIndexIsProperty.Add(whichIndexIsThis);

                // Change the property value back to its initial state.
                var unboxedValue = Unbox(initialValues[whichIndexIsThis], properties[i]);
                properties[i].SetValue(effect, unboxedValue);
                AssertPropertyValuesAreEqual(unboxedValue, properties[i].GetValue(effect));
                Assert.IsTrue(BoxedValuesAreEqual(initialValues[whichIndexIsThis], effectProperties[whichIndexIsThis], properties[i]));

                // Validate that IGraphicsEffectD2D1Interop agrees with what we think the type and index of this property is.
                int mappingIndex;
                EffectPropertyMapping mapping;

                EffectAccessor.GetNamedPropertyMapping(effect, properties[i].Name, out mappingIndex, out mapping);

                int expectedMappingIndex = whichIndexIsThis;

                if (effectProperties is FilteredViewOfList <object> )
                {
                    expectedMappingIndex = ((FilteredViewOfList <object>)effectProperties).GetOriginalIndex(expectedMappingIndex);
                }

                Assert.AreEqual(expectedMappingIndex, mappingIndex);

                var expectedMapping = GetExpectedPropertyMapping(properties[i], effectProperties[whichIndexIsThis]);
                Assert.AreEqual(expectedMapping, mapping);
            }

            // Should not have any duplicate property mappings.
            Assert.AreEqual(whichIndexIsProperty.Count, whichIndexIsProperty.Distinct().Count());
        }
コード例 #25
0
        private async void UpdateEffect()
        {
            if (_compositor != null)
            {
                ComboBoxItem     item                 = EffectSelection.SelectedValue as ComboBoxItem;
                IGraphicsEffect  graphicsEffect       = null;
                CompositionBrush secondaryBrush       = null;
                string[]         animatableProperties = null;

                //
                // Create the appropriate effect graph and resources
                //

                switch ((EffectTypes)item.Tag)
                {
                case EffectTypes.Desaturation:
                {
                    graphicsEffect = new SaturationEffect()
                    {
                        Saturation = 0.0f,
                        Source     = new CompositionEffectSourceParameter("ImageSource")
                    };
                }
                break;

                case EffectTypes.Hue:
                {
                    graphicsEffect = new HueRotationEffect()
                    {
                        Name   = "Hue",
                        Angle  = 3.14f,
                        Source = new CompositionEffectSourceParameter("ImageSource")
                    };
                    animatableProperties = new[] { "Hue.Angle" };
                }
                break;

                case EffectTypes.VividLight:
                {
                    graphicsEffect = new BlendEffect()
                    {
                        Mode       = BlendEffectMode.VividLight,
                        Foreground = new ColorSourceEffect()
                        {
                            Name  = "Base",
                            Color = Color.FromArgb(255, 80, 40, 40)
                        },
                        Background = new CompositionEffectSourceParameter("ImageSource"),
                    };
                    animatableProperties = new[] { "Base.Color" };
                }
                break;

                case EffectTypes.Mask:
                {
                    graphicsEffect = new CompositeEffect()
                    {
                        Mode    = CanvasComposite.DestinationOver,
                        Sources =
                        {
                            new CompositeEffect()
                            {
                                Mode    = CanvasComposite.DestinationIn,
                                Sources =
                                {
                                    new CompositionEffectSourceParameter("ImageSource"),
                                    new CompositionEffectSourceParameter("SecondSource")
                                }
                            },
                            new ColorSourceEffect()
                            {
                                Color = Color.FromArgb(200, 255, 255, 255)
                            },
                        }
                    };

                    CompositionDrawingSurface backgroundSurface = await SurfaceLoader.LoadFromUri(new Uri("ms-appx:///Samples/SDK 14393/ForegroundFocusEffects/mask.png"));

                    CompositionSurfaceBrush maskBrush = _compositor.CreateSurfaceBrush(backgroundSurface);
                    maskBrush.Stretch     = CompositionStretch.UniformToFill;
                    maskBrush.CenterPoint = _destinationSprite.Size * .5f;
                    secondaryBrush        = maskBrush;
                }
                break;

                case EffectTypes.Blur:
                {
                    graphicsEffect = new GaussianBlurEffect()
                    {
                        BlurAmount   = 20,
                        Source       = new CompositionEffectSourceParameter("ImageSource"),
                        Optimization = EffectOptimization.Balanced,
                        BorderMode   = EffectBorderMode.Hard,
                    };
                }
                break;

                case EffectTypes.LightenBlur:
                {
                    graphicsEffect = new ArithmeticCompositeEffect()
                    {
                        Source1Amount  = .4f,
                        Source2Amount  = .6f,
                        MultiplyAmount = 0,
                        Source1        = new ColorSourceEffect()
                        {
                            Name  = "Base",
                            Color = Color.FromArgb(255, 255, 255, 255),
                        },
                        Source2 = new GaussianBlurEffect()
                        {
                            BlurAmount   = 20,
                            Source       = new CompositionEffectSourceParameter("ImageSource"),
                            Optimization = EffectOptimization.Balanced,
                            BorderMode   = EffectBorderMode.Hard,
                        }
                    };
                }
                break;

                case EffectTypes.DarkenBlur:
                {
                    graphicsEffect = new ArithmeticCompositeEffect()
                    {
                        Source1Amount  = .4f,
                        Source2Amount  = .6f,
                        MultiplyAmount = 0,
                        Source1        = new ColorSourceEffect()
                        {
                            Name  = "Base",
                            Color = Color.FromArgb(255, 0, 0, 0),
                        },
                        Source2 = new GaussianBlurEffect()
                        {
                            BlurAmount   = 20,
                            Source       = new CompositionEffectSourceParameter("ImageSource"),
                            Optimization = EffectOptimization.Balanced,
                            BorderMode   = EffectBorderMode.Hard,
                        }
                    };
                }
                break;

                case EffectTypes.RainbowBlur:
                {
                    graphicsEffect = new ArithmeticCompositeEffect()
                    {
                        Source1Amount  = .3f,
                        Source2Amount  = .7f,
                        MultiplyAmount = 0,
                        Source1        = new ColorSourceEffect()
                        {
                            Name  = "Base",
                            Color = Color.FromArgb(255, 0, 0, 0),
                        },
                        Source2 = new GaussianBlurEffect()
                        {
                            BlurAmount   = 20,
                            Source       = new CompositionEffectSourceParameter("ImageSource"),
                            Optimization = EffectOptimization.Balanced,
                            BorderMode   = EffectBorderMode.Hard,
                        }
                    };
                    animatableProperties = new[] { "Base.Color" };
                }
                break;

                default:
                    break;
                }

                // Create the effect factory and instantiate a brush
                CompositionEffectFactory _effectFactory = _compositor.CreateEffectFactory(graphicsEffect, animatableProperties);
                CompositionEffectBrush   brush          = _effectFactory.CreateBrush();

                // Set the destination brush as the source of the image content
                brush.SetSourceParameter("ImageSource", _compositor.CreateBackdropBrush());

                // If his effect uses a secondary brush, set it now
                if (secondaryBrush != null)
                {
                    brush.SetSourceParameter("SecondSource", secondaryBrush);
                }

                // Update the destination layer with the fully configured brush
                _destinationSprite.Brush = brush;
            }
        }
コード例 #26
0
        private void EffectToString(StringBuilder sb, int indent, IGraphicsEffect effect, CompositionEffectBrush brush)
        {
            const int indentIncrement = 4;
            Type      type            = effect.GetType();

            sb.AppendFormat("{0}{1}\r\n{0}{{\r\n", Indent(indent), type.Name);

            Dictionary <string, object> expandedProperties = new Dictionary <string, object>();

            indent += indentIncrement;
            foreach (PropertyInfo info in effect.GetType().GetProperties())
            {
                string propertyName = info.Name.ToLower();
                if (propertyName == "cacheoutput" ||
                    propertyName == "bufferprecision" ||
                    propertyName == "colorhdr" ||
                    propertyName == "issupported" ||
                    propertyName == "clampoutput" ||
                    propertyName == "name" ||
                    propertyName == "alphamode")
                {
                    continue;
                }

                object obj = info.GetValue(effect);
                if (obj != null)
                {
                    if (obj is IGraphicsEffect || obj is IList <IGraphicsEffectSource> )
                    {
                        expandedProperties.Add(info.Name, obj);
                    }
                    else
                    {
                        if (obj is CompositionEffectSourceParameter)
                        {
                            CompositionEffectSourceParameter param = (CompositionEffectSourceParameter)obj;
                            CompositionBrush sourceBrush           = brush.GetSourceParameter(param.Name);

                            string s = String.Format("{0}{1} :\r\n{0}{{\r\n", Indent(indent), info.Name);
                            sb.Append(s);
                            BrushToString(sb, indent + indentIncrement, sourceBrush);
                            sb.AppendFormat("{0}}}\r\n", Indent(indent));
                        }
                        else
                        {
                            sb.AppendFormat("{0}{1} : {2}\r\n", Indent(indent), info.Name, Helpers.ToString(obj));
                        }
                    }
                }
            }

            // Moved all of the nested source properties to the end of the list
            foreach (KeyValuePair <string, object> entry in expandedProperties)
            {
                string name = entry.Key;
                object obj  = entry.Value;

                if (obj is IGraphicsEffect)
                {
                    string s = String.Format("{0}{1} :\r\n{0}{{\r\n", Indent(indent), name);
                    sb.Append(s);
                    EffectToString(sb, indent + indentIncrement, (IGraphicsEffect)obj, brush);
                    sb.AppendFormat("{0}}}\r\n", Indent(indent));
                }
                else if (obj is IList <IGraphicsEffectSource> )
                {
                    IList <IGraphicsEffectSource> list = (IList <IGraphicsEffectSource>)obj;

                    sb.AppendFormat("{0}{1} :\r\n{0}[\r\n", Indent(indent), name);
                    foreach (IGraphicsEffectSource source in list)
                    {
                        EffectToString(sb, indent + indentIncrement, (IGraphicsEffect)source, brush);
                    }
                    sb.AppendFormat("{0}]\r\n", Indent(indent));
                }
            }

            indent -= indentIncrement;
            sb.AppendFormat("{0}}}\r\n", Indent(indent));
        }