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(); }
public async Task RenderWithZeroWidthFocusAreaSuccedes() { var verticalZeroBand = new FocusBand(new Point(0.3, 0.5), new Point(0.3, 0.5)); await RenderEffect(verticalZeroBand, DepthOfFieldQuality.Full); var horizontalZeroBand = new FocusBand(new Point(0.5, 0.7), new Point(0.5, 0.7)); await RenderEffect(horizontalZeroBand, DepthOfFieldQuality.Full); }
public async Task RenderWithFullFocusAreaSuccedes() { var verticalFullBand = new FocusBand(new Point(0.0, 0.5), new Point(1.0, 0.5)); await RenderEffect(verticalFullBand, DepthOfFieldQuality.Full); var horizontalFullBand = new FocusBand(new Point(0.5, 0.0), new Point(0.5, 1.0)); await RenderEffect(horizontalFullBand, DepthOfFieldQuality.Full); }
private static async Task RenderEffect(FocusBand focusBand, DepthOfFieldQuality quality, [CallerMemberName] string testName = "") { using (var source = await KnownImages.Nurse.GetImageSourceAsync()) using (var effect = new LensTiltDepthOfFieldEffect(source, focusBand, 1.0, 1.0, quality)) using (var renderer = new JpegRenderer(effect)) { var buffer = await renderer.RenderAsync(); await FileUtilities.SaveToPicturesLibraryAsync(buffer, "LensTiltDepthOfFieldEffectTest_" + testName + ".jpg"); } }
/// <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); }
/// <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; }
protected override MaybeTask <IImageProvider> GetEffectInternalAsync(IImageProvider source, Windows.Foundation.Size sourceSize, Windows.Foundation.Size renderSize) { if (m_effectEffect == null) { m_focus = new FocusBand(new Point(0.5, 0.3), new Point(0.5, 0.4)); m_effectEffect = new LensTiltDepthOfFieldEffect(source, m_focus, 1.0, 1.0, DepthOfFieldQuality.Preview); } else if (m_effectEffect.Source != source) { m_effectEffect.Source = source; } return(new MaybeTask <IImageProvider>(m_effectEffect)); }
public static Func<double, Point> CreateFunction(FocusBand band) { double xDiff = band.Edge1.X - band.Edge2.X; Func<double, Point> lineFunction; if (Math.Abs(xDiff) < 1e-3) { //special case to avoid divide by zero lineFunction = (x) => new Point(band.Edge1.X, x); } else { double slope = (band.Edge2.Y - band.Edge1.Y) / (band.Edge2.X - band.Edge1.X); double yIntercept = band.Edge1.Y - band.Edge1.X * slope; lineFunction = (x) => new Point(x, slope * x + yIntercept); } return lineFunction; }
public static Func <double, Point> CreateFunction(FocusBand band) { double xDiff = band.Edge1.X - band.Edge2.X; Func <double, Point> lineFunction; if (Math.Abs(xDiff) < 1e-3) { //special case to avoid divide by zero lineFunction = (x) => new Point(band.Edge1.X, x); } else { double slope = (band.Edge2.Y - band.Edge1.Y) / (band.Edge2.X - band.Edge1.X); double yIntercept = band.Edge1.Y - band.Edge1.X * slope; lineFunction = (x) => new Point(x, slope * x + yIntercept); } return(lineFunction); }
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(); }
public GradientLine(FocusBand band) { m_focusBand = band; IsVertical = (band.Edge1.X - band.Edge2.X) < 1e-3; IsHorizontal = (band.Edge1.Y - band.Edge2.Y) < 1e-3; }