예제 #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(LinearGradient gradient, FocusBand focusBand, Size sourceSize, KernelGenerator edge1KernelGenerator, KernelGenerator edge2KernelGenerator, bool applySmallBlurFocusArea)
		{
			var blurArea1FirstOffset = GetOffset(gradient, focusBand.Edge1);
			var blurArea2FirstOffset = GetOffset(gradient, focusBand.Edge2);

			var focusBandEdge1Pixels = new Point(focusBand.Edge1.X * sourceSize.Width, focusBand.Edge1.Y * sourceSize.Height);
			var focusBandEdge2Pixels = new Point(focusBand.Edge2.X * sourceSize.Width, focusBand.Edge2.Y * sourceSize.Height);

			var focusBandWidth = Math.Abs(blurArea1FirstOffset - blurArea2FirstOffset);
            var focusBandWidthPixels = Distance(focusBandEdge1Pixels, focusBandEdge2Pixels);

            double blurAreaWidth;
            if (focusBandWidthPixels > 0)
            {
                var scaleFactor = focusBandWidth / focusBandWidthPixels;

                var blurAreaWidthPixels = (sourceSize.Height - focusBandWidthPixels) / 2 * 0.9;

                if (blurAreaWidthPixels < 1.0)
                {
                    gradient.Stops = new[] { new GradientStop() { Offset = 0.5, Color = Color.FromArgb(255, 0, 0, 0) } };
                    return;
                }

                blurAreaWidth = blurAreaWidthPixels * scaleFactor;
            }
            else
            {
                blurAreaWidth = 0.5;
                applySmallBlurFocusArea = true;
            }

			double blurArea1LastOffset;
			double blurArea2LastOffset;

			if (blurArea1FirstOffset > blurArea2FirstOffset)
			{
				blurArea1LastOffset = blurArea1FirstOffset + blurAreaWidth;
				blurArea2LastOffset = blurArea2FirstOffset - blurAreaWidth;
			}
			else
			{
				blurArea1LastOffset = blurArea1FirstOffset - blurAreaWidth;
				blurArea2LastOffset = blurArea2FirstOffset + blurAreaWidth;
			}

			var stops1 = GetGradientStops(gradient, applySmallBlurFocusArea, edge1KernelGenerator, blurArea1FirstOffset, blurArea1LastOffset);
			var stops2 = GetGradientStops(gradient, applySmallBlurFocusArea, edge2KernelGenerator, blurArea2FirstOffset, blurArea2LastOffset, (byte)(edge1KernelGenerator.GetKernelBands().Count));

			List<GradientStop> stops = new List<GradientStop>();
			stops.AddRange(stops1);
			stops.AddRange(stops2);

			var validStops = EnsureMinDiffBetweenPoints(stops);

			gradient.Stops = validStops.ToArray();
		}
		/// <summary>
		/// Provides a configured LinearGradient that can be used in combination with a GradientImageSource to provide a mask for the LensBlurEffect.
		/// Generates a map for BlendEffect.
		/// </summary>
		/// <param name="band">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="kernelSpanFromEdge1">Strength at Edge1.</param>
		/// <param name="kernelSpanFromEdge2">Strength at Edge2.</param>
		/// <returns>A LinearGradient that can be used in combination with a GradientImageSource to be used by LensBlur.</returns>

		public static LinearGradient GenerateGradient(FocusBand band, Size sourceSize, KernelGenerator edge1KernelGenerator, KernelGenerator edge2KernelGenerator, bool applySmallBlurFocusArea)
		{
			var gradient = new LinearGradient();

			var lineFunction = GradientLine.CreateFunction(band);

			SetGradientPoints(gradient, lineFunction);
            SetGradientStops(gradient, band, sourceSize, edge1KernelGenerator, edge2KernelGenerator, applySmallBlurFocusArea);

			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();
		}
예제 #6
0
        private static void SetGradientStops(LinearGradient gradient, FocusBand focusBand, Size sourceSize, KernelGenerator edge1KernelGenerator, KernelGenerator edge2KernelGenerator, bool applySmallBlurFocusArea)
        {
            var blurArea1FirstOffset = GetOffset(gradient, focusBand.Edge1);
            var blurArea2FirstOffset = GetOffset(gradient, focusBand.Edge2);

            var focusBandEdge1Pixels = new Point(focusBand.Edge1.X * sourceSize.Width, focusBand.Edge1.Y * sourceSize.Height);
            var focusBandEdge2Pixels = new Point(focusBand.Edge2.X * sourceSize.Width, focusBand.Edge2.Y * sourceSize.Height);

            var focusBandWidth       = Math.Abs(blurArea1FirstOffset - blurArea2FirstOffset);
            var focusBandWidthPixels = Distance(focusBandEdge1Pixels, focusBandEdge2Pixels);

            double blurAreaWidth;

            if (focusBandWidthPixels > 0)
            {
                var scaleFactor = focusBandWidth / focusBandWidthPixels;

                var blurAreaWidthPixels = (sourceSize.Height - focusBandWidthPixels) / 2 * 0.9;

                if (blurAreaWidthPixels < 1.0)
                {
                    gradient.Stops = new[] { new GradientStop()
                                             {
                                                 Offset = 0.5, Color = Color.FromArgb(255, 0, 0, 0)
                                             } };
                    return;
                }

                blurAreaWidth = blurAreaWidthPixels * scaleFactor;
            }
            else
            {
                blurAreaWidth           = 0.5;
                applySmallBlurFocusArea = true;
            }

            double blurArea1LastOffset;
            double blurArea2LastOffset;

            if (blurArea1FirstOffset > blurArea2FirstOffset)
            {
                blurArea1LastOffset = blurArea1FirstOffset + blurAreaWidth;
                blurArea2LastOffset = blurArea2FirstOffset - blurAreaWidth;
            }
            else
            {
                blurArea1LastOffset = blurArea1FirstOffset - blurAreaWidth;
                blurArea2LastOffset = blurArea2FirstOffset + blurAreaWidth;
            }

            var stops1 = GetGradientStops(gradient, applySmallBlurFocusArea, edge1KernelGenerator, blurArea1FirstOffset, blurArea1LastOffset);
            var stops2 = GetGradientStops(gradient, applySmallBlurFocusArea, edge2KernelGenerator, blurArea2FirstOffset, blurArea2LastOffset, (byte)(edge1KernelGenerator.GetKernelBands().Count));

            List <GradientStop> stops = new List <GradientStop>();

            stops.AddRange(stops1);
            stops.AddRange(stops2);

            var validStops = EnsureMinDiffBetweenPoints(stops);

            gradient.Stops = validStops.ToArray();
        }
예제 #7
0
        /// <summary>
        /// Provides a configured LinearGradient that can be used in combination with a GradientImageSource to provide a mask for the LensBlurEffect.
        /// Generates a map for BlendEffect.
        /// </summary>
        /// <param name="band">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="kernelSpanFromEdge1">Strength at Edge1.</param>
        /// <param name="kernelSpanFromEdge2">Strength at Edge2.</param>
        /// <returns>A LinearGradient that can be used in combination with a GradientImageSource to be used by LensBlur.</returns>

        public static LinearGradient GenerateGradient(FocusBand band, Size sourceSize, KernelGenerator edge1KernelGenerator, KernelGenerator edge2KernelGenerator, bool applySmallBlurFocusArea)
        {
            var gradient = new LinearGradient();

            var lineFunction = GradientLine.CreateFunction(band);

            SetGradientPoints(gradient, lineFunction);
            SetGradientStops(gradient, band, sourceSize, edge1KernelGenerator, edge2KernelGenerator, applySmallBlurFocusArea);

            return(gradient);
        }
예제 #8
0
        private static List <GradientStop> GetGradientStops(LinearGradient gradient, bool applySmallBlurFocusArea, KernelGenerator kernelGenerator, double firstStopOffset, double lastStopOffset, byte firstKernelIndex = 0)
        {
            var stops = new List <GradientStop>();

            if (kernelGenerator.GetKernelBands().Count > 0)
            {
                double sumOfBandWidths = kernelGenerator.GetKernelBands().Select(band => band.Width).Sum();

                var focusAreaColor = GetFocusAreaColor(applySmallBlurFocusArea);
                stops.Add(new GradientStop()
                {
                    Color = Color.FromArgb(255, focusAreaColor, focusAreaColor, focusAreaColor), Offset = firstStopOffset
                });

                var currentStopOffset = lastStopOffset - firstStopOffset > 0
                                        ? firstStopOffset + minDiffBetweenStops
                                        : firstStopOffset - minDiffBetweenStops;

                var kernelBands = kernelGenerator.GetKernelBands();

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

                stops = EnsureMinDiffBetweenPoints(stops);
            }

            return(stops);
        }
예제 #9
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();
        }
		private static List<GradientStop> GetGradientStops(LinearGradient gradient, bool applySmallBlurFocusArea, KernelGenerator kernelGenerator, double firstStopOffset, double lastStopOffset, byte firstKernelIndex = 0)
		{
			var stops = new List<GradientStop>();

			if (kernelGenerator.GetKernelBands().Count > 0)
			{
				double sumOfBandWidths = kernelGenerator.GetKernelBands().Select(band => band.Width).Sum();

				var focusAreaColor = GetFocusAreaColor(applySmallBlurFocusArea);
				stops.Add(new GradientStop() { Color = Color.FromArgb(255, focusAreaColor, focusAreaColor, focusAreaColor), Offset = firstStopOffset });

				var currentStopOffset = lastStopOffset - firstStopOffset > 0
					? firstStopOffset + minDiffBetweenStops
					: firstStopOffset - minDiffBetweenStops;

				var kernelBands = kernelGenerator.GetKernelBands();

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

				stops = EnsureMinDiffBetweenPoints(stops);
			}

			return stops;
		}