Пример #1
0
        /// <summary>
        /// Provides a configured LinearGradient that can be used in combination with a GradientImageSource to provide a mask for the LensBlurEffect.
        /// It will expect the LensBlur will be blurred with 1 kernel when the double is different from None.
        /// </summary>
        /// <param name="ellipse">The band that represents the focus area in the image. Pixels within this band won't be blurred.
        /// Areas outside of the area will be progressively more blurred as the distance from the focus band increases.</param>
        /// <param name="strength">Strength of the blur.</param>
        /// <returns>A LinearGradient that can be used in combination with a GradientImageSource to be used by LensBlur.</returns>
        public static RadialGradient GenerateGradient(FocusEllipse ellipse, KernelGenerator kernelGenerator)
        {
            if (kernelGenerator.GetKernelBands().Count == 0)
            {
                return(null);
            }

            EllipseRadius maxBlurRadius = null;

            if ((ellipse.Radius.X < minDiffBetweenStops) && (ellipse.Radius.Y < minDiffBetweenStops))
            {
                maxBlurRadius = new EllipseRadius(minDiffBetweenStops, minDiffBetweenStops);
            }
            else
            {
                double factor       = 0.9;
                bool   widthGtHight = ellipse.Radius.X > ellipse.Radius.Y;

                if (widthGtHight)
                {
                    maxBlurRadius = new EllipseRadius(factor, factor * ellipse.Radius.Y / ellipse.Radius.X);
                }
                else
                {
                    maxBlurRadius = new EllipseRadius(factor * ellipse.Radius.X / ellipse.Radius.Y, factor);
                }
            }

            var gradient = new RadialGradient(ellipse.Center, maxBlurRadius);

            SetGradientStops(gradient, ellipse, maxBlurRadius, kernelGenerator);

            return(gradient);
        }
		/// <summary>
		/// Provides a configured LinearGradient that can be used in combination with a GradientImageSource to provide a mask for the LensBlurEffect.
		/// It will expect the LensBlur will be blurred with 1 kernel when the double is different from None.
		/// </summary>
		/// <param name="ellipse">The band that represents the focus area in the image. Pixels within this band won't be blurred. 
		/// Areas outside of the area will be progressively more blurred as the distance from the focus band increases.</param>
		/// <param name="strength">Strength of the blur.</param>
		/// <returns>A LinearGradient that can be used in combination with a GradientImageSource to be used by LensBlur.</returns>
		public static RadialGradient GenerateGradient(FocusEllipse ellipse, KernelGenerator kernelGenerator)
		{
			if (kernelGenerator.GetKernelBands().Count == 0)
			{
				return null;
			}

			EllipseRadius maxBlurRadius = null;

            if ((ellipse.Radius.X < minDiffBetweenStops) && (ellipse.Radius.Y < minDiffBetweenStops))
            {
                maxBlurRadius = new EllipseRadius(minDiffBetweenStops, minDiffBetweenStops);
            }
            else
            {
                double factor = 0.9;
                bool widthGtHight = ellipse.Radius.X > ellipse.Radius.Y;
                
                if (widthGtHight)
                {
                    maxBlurRadius = new EllipseRadius(factor, factor * ellipse.Radius.Y / ellipse.Radius.X);
                }
                else
                {
                    maxBlurRadius = new EllipseRadius(factor * ellipse.Radius.X / ellipse.Radius.Y, factor);
                }
            }

			var gradient = new RadialGradient(ellipse.Center, maxBlurRadius);
			SetGradientStops(gradient, ellipse, maxBlurRadius, kernelGenerator);

			return gradient;
		}
		private static void SetGradientStops(RadialGradient gradient, FocusEllipse ellipse, EllipseRadius maxBlurRadius, KernelGenerator kernelGenerator)
		{
			var stops = new List<GradientStop>();

            double firstStopOffset;

            if (maxBlurRadius.X > minDiffBetweenStops)
            {
                firstStopOffset = ellipse.Radius.X / maxBlurRadius.X;
                
                //Add the focus area at the center of the ellipse.
                stops.Add(new GradientStop() { Color = Color.FromArgb(255, 0, 0, 0), Offset = 0 });
                stops.Add(new GradientStop() { Color = Color.FromArgb(255, 0, 0, 0), Offset = firstStopOffset });
            }
            else
            {
                firstStopOffset = minDiffBetweenStops;
            }

			double sumOfBandWidths = kernelGenerator.GetKernelBands().Select(band => band.Width).Sum();
			var currentStopOffset = firstStopOffset + minDiffBetweenStops;

			var kernelBands = kernelGenerator.GetKernelBands();

			byte kernelIndex = 0;
			foreach (var band in kernelBands)
			{
				kernelIndex++;
				stops.Add(new GradientStop() { Color = Color.FromArgb(255, kernelIndex, kernelIndex, kernelIndex), Offset = currentStopOffset });
				currentStopOffset = currentStopOffset + (band.Width / sumOfBandWidths) * (1 - firstStopOffset) * FocusToBlurTransitionWidth;
			}
			stops.Add(new GradientStop() { Color = Color.FromArgb(255, kernelIndex, kernelIndex, kernelIndex), Offset = currentStopOffset });

			var validStops = EnsureMinDiffBetweenPoints(stops);

			gradient.Stops = validStops.ToArray();
		}
Пример #4
0
        private protected override void UpdatePaintCore(SKPaint paint, SKRect bounds)
        {
            var center         = EllipseCenter.ToSKPoint();
            var gradientOrigin = EllipseCenter.ToSKPoint() + GradientOriginOffset.ToSKPoint();
            var radius         = EllipseRadius.ToSKPoint();
            var transform      = CreateTransformMatrix(bounds);

            // Transform the points into absolute coordinates.
            if (MappingMode == CompositionMappingMode.Relative)
            {
                // If the point are provided relative they must be multiplied by bounds.
                center.X *= bounds.Width;
                center.Y *= bounds.Height;

                gradientOrigin.X *= bounds.Width;
                gradientOrigin.Y *= bounds.Height;

                radius.X *= bounds.Width;
                radius.Y *= bounds.Height;
            }

            // Translate gradient points by bounds offset.
            center.X += bounds.Left;
            center.Y += bounds.Top;

            gradientOrigin.X += bounds.Left;
            gradientOrigin.Y += bounds.Top;
            //

            // SkiaSharp does not allow explicit definition of RadiusX and RadiusY.
            // Compute transformation matrix to compensate.
            ComputeRadiusAndScale(center, radius.X, radius.Y, out float gradientRadius, out SKMatrix matrix);

            // Clean up old shader
            if (paint.Shader != null)
            {
                paint.Shader.Dispose();
                paint.Shader = null;
            }

            if (gradientRadius > 0)
            {
                // Create radial gradient shader.
                SKShader shader =
                    SKShader.CreateTwoPointConicalGradient(
                        /* start */ gradientOrigin, /* start radius */ 0,
                        /* end */ center, /* gradient radius */ gradientRadius,
                        Colors, ColorPositions,
                        TileMode, transform.PreConcat(matrix));

                paint.Shader = shader;
                paint.Color  = SKColors.Black.WithAlpha((byte)(Compositor.CurrentOpacity * 255));
            }
            else
            {
                // With radius equal to 0, SkiaSharp does not draw anything.
                // But we expect last gradient color.

                // If there are no gradient stops available, use transparent.
                SKColor color = SKColors.Transparent;
                if (Colors !.Length > 0)
                {
                    color = Colors[Colors.Length - 1];
                }

                double alpha = (color.Alpha / 255.0) * Compositor.CurrentOpacity;
                paint.Color = color.WithAlpha((byte)(alpha * 255));
            }
        }
Пример #5
0
 public FocusEllipse(double x, double y, double xRadius, double yRadius)
 {
     Center = new Point(x, y);
     Radius = new EllipseRadius(xRadius, yRadius);
 }
Пример #6
0
 /// <summary>
 /// Creates and initialized a new FocusEllipse with specified center and radius.
 /// </summary>
 /// <param name="center">The center of the ellipse. Expressed in the unit coordinate space of the image area,
 /// i.e., the top left corner of the image is at (0.0), and the bottom right corner is at (1, 1).</param>
 /// <param name="radius">The radius of the ellipse. Expressed in the unit coordinate space of the image area,
 /// i.e., the top left corner of the image is at (0.0), and the bottom right corner is at (1, 1).</param>
 public FocusEllipse(Point center, EllipseRadius radius)
 {
     Center = center;
     Radius = radius;
 }
Пример #7
0
        private static void SetGradientStops(RadialGradient gradient, FocusEllipse ellipse, EllipseRadius maxBlurRadius, KernelGenerator kernelGenerator)
        {
            var stops = new List <GradientStop>();

            double firstStopOffset;

            if (maxBlurRadius.X > minDiffBetweenStops)
            {
                firstStopOffset = ellipse.Radius.X / maxBlurRadius.X;

                //Add the focus area at the center of the ellipse.
                stops.Add(new GradientStop()
                {
                    Color = Color.FromArgb(255, 0, 0, 0), Offset = 0
                });
                stops.Add(new GradientStop()
                {
                    Color = Color.FromArgb(255, 0, 0, 0), Offset = firstStopOffset
                });
            }
            else
            {
                firstStopOffset = minDiffBetweenStops;
            }

            double sumOfBandWidths   = kernelGenerator.GetKernelBands().Select(band => band.Width).Sum();
            var    currentStopOffset = firstStopOffset + minDiffBetweenStops;

            var kernelBands = kernelGenerator.GetKernelBands();

            byte kernelIndex = 0;

            foreach (var band in kernelBands)
            {
                kernelIndex++;
                stops.Add(new GradientStop()
                {
                    Color = Color.FromArgb(255, kernelIndex, kernelIndex, kernelIndex), Offset = currentStopOffset
                });
                currentStopOffset = currentStopOffset + (band.Width / sumOfBandWidths) * (1 - firstStopOffset) * FocusToBlurTransitionWidth;
            }
            stops.Add(new GradientStop()
            {
                Color = Color.FromArgb(255, kernelIndex, kernelIndex, kernelIndex), Offset = currentStopOffset
            });

            var validStops = EnsureMinDiffBetweenPoints(stops);

            gradient.Stops = validStops.ToArray();
        }
Пример #8
0
		public FocusEllipse(double x, double y, double xRadius, double yRadius)
		{
			Center = new Point(x, y);
			Radius = new EllipseRadius(xRadius, yRadius);
		}
Пример #9
0
 /// <summary>
 /// Creates and initialized a new FocusEllipse with specified center and radius.
 /// </summary>
 /// <param name="center">The center of the ellipse. Expressed in the unit coordinate space of the image area,
 /// i.e., the top left corner of the image is at (0.0), and the bottom right corner is at (1, 1).</param>
 /// <param name="radius">The radius of the ellipse. Expressed in the unit coordinate space of the image area,
 /// i.e., the top left corner of the image is at (0.0), and the bottom right corner is at (1, 1).</param>
 public FocusEllipse(Point center, EllipseRadius radius)
 {
     Center = center;
     Radius = radius;
 }