protected override sealed void CreateImage(ImageGenerationContext context) { base.CreateImage(context); Rect bounds = new Rect(StrokeWidth / 2, StrokeWidth / 2, CalculatedWidth - StrokeWidth, CalculatedHeight - StrokeWidth); Brush brush = Fill.GetBrush(); Pen pen = GetPen(); DrawingVisual dv = new DrawingVisual(); DrawingContext dc = dv.RenderOpen(); if (Roundness == 0) { dc.DrawRectangle(brush, pen, bounds); } else { dc.DrawRoundedRectangle(brush, pen, bounds, Roundness, Roundness); } dc.Close(); RenderTargetBitmap rtb = RenderTargetBitmapUtility.CreateRenderTargetBitmap(CalculatedWidth, CalculatedHeight); rtb.Render(dv); Bitmap = new FastBitmap(rtb); }
protected sealed override void CreateImage() { base.CreateImage(); Rect bounds = new Rect(StrokeWidth / 2, StrokeWidth / 2, CalculatedWidth - StrokeWidth, CalculatedHeight - StrokeWidth); Brush brush = Fill.GetBrush(); PointCollection points = GetPoints(bounds); PathGeometry geometry = CanonicalSplineHelper.CreateSpline(points, Roundness / 100.0, null, true, true, 0.25); Pen pen = GetPen(); DrawingVisual dv = new DrawingVisual(); DrawingContext dc = dv.RenderOpen(); // Draw polygon. dc.DrawGeometry(brush, pen, geometry); dc.Close(); RenderTargetBitmap rtb = RenderTargetBitmapUtility.CreateRenderTargetBitmap(CalculatedWidth, CalculatedHeight); rtb.Render(dv); Bitmap = new FastBitmap(rtb); }
protected override Effect GetEffect(ImageGenerationContext context, FastBitmap source) { // Fill temporary graphics buffer with mask (currently always a rectangle). DrawingVisual dv = new DrawingVisual { Effect = new BlurEffect { Radius = Radius, KernelType = KernelType.Gaussian } }; DrawingContext dc = dv.RenderOpen(); dc.DrawImage(source.InnerBitmap, new Rect(0, 0, source.Width, source.Height)); dc.Close(); RenderTargetBitmap rtb = RenderTargetBitmapUtility.CreateRenderTargetBitmap(source.Width, source.Height); rtb.Render(dv); Brush blurredImage = new ImageBrush(rtb); return(new UnsharpMaskEffect { BlurMask = blurredImage, Amount = Amount / 100.0, Threshold = Threshold }); }
protected override void CreateImage() { // If width and height are not set, we need to measure the string. int calculatedWidth, calculatedHeight; Size measuredSize = MeasureString(); if (Width == null || Height == null) { double width = Width ?? measuredSize.Width; double height = Height ?? measuredSize.Height; calculatedWidth = (int)width; calculatedHeight = (int)height; } else // otherwise just create the image at the desired size { calculatedWidth = Width.Value; calculatedHeight = Height.Value; } #region Draw text DrawingVisual dv = new DrawingVisual(); DrawingContext dc = dv.RenderOpen(); //RenderOptions.SetClearTypeHint(dv, ClearTypeHint.Auto); TextOptions.SetTextRenderingMode(dv, TextRenderingMode.Auto); //TextOptions.SetTextFormattingMode(dv, TextFormattingMode.Ideal) UseFormattedText(ft => { Pen pen = null; if (StrokeWidth > 0 && StrokeColor != null) { pen = new Pen(new SolidColorBrush(StrokeColor.Value.ToWpfColor()), StrokeWidth); } // Calculate position to draw text at, based on vertical text alignment. int x = CalculateHorizontalPosition((int)measuredSize.Width); int y = CalculateVerticalPosition((int)measuredSize.Height); dc.DrawGeometry(new SolidColorBrush(ForeColor.ToWpfColor()), pen, ft.BuildGeometry(new Point(x, y))); }); dc.Close(); RenderTargetBitmap rtb = RenderTargetBitmapUtility.CreateRenderTargetBitmap(calculatedWidth, calculatedHeight); rtb.Render(dv); #endregion Bitmap = new FastBitmap(rtb); }
public static FastBitmap BlendLayers(FastBitmap output, IEnumerable <Layer> layers) { DrawingVisual dv = new DrawingVisual(); RenderTargetBitmap rtb = RenderTargetBitmapUtility.CreateRenderTargetBitmap(output.Width, output.Height); // Draw background. var dc2 = dv.RenderOpen(); dc2.DrawImage(output.InnerBitmap, new System.Windows.Rect(0, 0, output.Width, output.Height)); dc2.Close(); rtb.Render(dv); var layersList = layers.ToList(); // As an optimisation, if BlendMode=Normal for all layers, don't use LayerBlenderEffect. // Just draw images directly using DrawImage. if (layersList.All(x => x.BlendMode == BlendMode.Normal)) { foreach (var layer in layersList) { DrawImage(dv, layer, rtb); } } else { ImageSource imageSource = output.InnerBitmap; foreach (var layer in layersList) { using (var effect = new LayerBlenderEffect(layer.BlendMode, output.Width, output.Height) { Background = new ImageBrush(imageSource) { TileMode = TileMode.None, Stretch = Stretch.None, ViewportUnits = BrushMappingMode.RelativeToBoundingBox, Viewport = new System.Windows.Rect(0, 0, 1, 1) } }) { dv.Effect = effect; DrawImage(dv, layer, rtb); } imageSource = rtb; } } return(new FastBitmap(rtb)); }
public static FastBitmap BlendLayers(FastBitmap output, IEnumerable <Layer> layers) { DrawingVisual dv = new DrawingVisual(); RenderTargetBitmap rtb = RenderTargetBitmapUtility.CreateRenderTargetBitmap(output.Width, output.Height); // Draw background. DrawingContext dc2 = dv.RenderOpen(); dc2.DrawImage(output.InnerBitmap, new System.Windows.Rect(0, 0, output.Width, output.Height)); dc2.Close(); rtb.Render(dv); ImageSource imageSource = output.InnerBitmap; foreach (Layer layer in layers) { using (var effect = new LayerBlenderEffect(layer.BlendMode, output.Width, output.Height) { Background = new ImageBrush(imageSource) { TileMode = TileMode.None, Stretch = Stretch.None, ViewportUnits = BrushMappingMode.RelativeToBoundingBox, Viewport = new System.Windows.Rect(0, 0, 1, 1) } }) { dv.Effect = effect; DrawingContext dc = dv.RenderOpen(); dc.PushTransform(new TranslateTransform(layer.X + layer.Padding.Left, layer.Y + layer.Padding.Top)); dc.DrawImage(layer.Bitmap.InnerBitmap, new System.Windows.Rect(0, 0, layer.Bitmap.Width, layer.Bitmap.Height)); dc.Pop(); dc.Close(); rtb.Render(dv); } imageSource = rtb; } return(new FastBitmap(rtb)); }
protected override Effect GetEffect(ImageGenerationContext context, FastBitmap source) { // Fill temporary graphics buffer with mask (currently always a rectangle). DrawingVisual dv = new DrawingVisual { Effect = new BlurEffect { Radius = Radius, KernelType = KernelType.Gaussian } }; DrawingContext dc = dv.RenderOpen(); dc.DrawRectangle(new SolidColorBrush(SWMColors.Transparent), null, new Rect(0, 0, source.Width, source.Height)); switch (Shape) { case FeatherShape.Rectangle: dc.DrawRectangle(new SolidColorBrush(SWMColors.White), null, new Rect(Radius, Radius, source.Width - Radius * 2, source.Height - Radius * 2)); break; case FeatherShape.Oval: dc.DrawEllipse(new SolidColorBrush(SWMColors.White), null, new Point(source.Width / 2.0, source.Height / 2.0), source.Width / 2 - Radius * 2, source.Height / 2 - Radius * 2); break; default: throw new NotSupportedException(); } dc.Close(); RenderTargetBitmap rtb = RenderTargetBitmapUtility.CreateRenderTargetBitmap(source.Width, source.Height); rtb.Render(dv); Brush alphaMask = new ImageBrush(rtb); return(new FeatherEffect { AlphaMask = alphaMask }); }
protected override void CreateImage() { string filename = FileSourceHelper.ResolveFileName(SourceFileName); MediaPlayer mediaPlayer = new MediaPlayer { ScrubbingEnabled = true }; object monitorObject = new object(); mediaPlayer.MediaOpened += (sender, e) => Monitor.Exit(monitorObject); Monitor.Enter(monitorObject); mediaPlayer.Open(new Uri(filename)); Monitor.Wait(monitorObject, 1000); int width = mediaPlayer.NaturalVideoWidth; int height = mediaPlayer.NaturalVideoHeight; // Seek to specified time. mediaPlayer.BufferingEnded += (sender, e) => Monitor.Exit(monitorObject); Monitor.Enter(monitorObject); mediaPlayer.Position = SnapshotTime; Monitor.Wait(monitorObject, 1000); DrawingVisual dv = new DrawingVisual(); DrawingContext dc = dv.RenderOpen(); dc.DrawVideo(mediaPlayer, new System.Windows.Rect(0, 0, width, height)); dc.Close(); RenderTargetBitmap rtb = RenderTargetBitmapUtility.CreateRenderTargetBitmap(width, height); rtb.Render(dv); Bitmap = new FastBitmap(rtb); mediaPlayer.Close(); }
/// <summary> /// Applies the filter to the specified <paramref name="bitmap"/>. This method /// first calls <see cref="ImageReplacementFilter.GetDestinationDimensions(FastBitmap, out Int32, out Int32)" /> /// to calculate the size of the destination image. Then it calls /// <see cref="ImageReplacementFilter.ApplyFilter(FastBitmap, DrawingContext, int, int)" /> /// which is where the overridden class implements its filter algorithm. /// </summary> /// <param name="bitmap"> /// Image to apply the <see cref="ImageReplacementFilter" /> to. /// </param> public sealed override void ApplyFilter(FastBitmap bitmap) { OnBeginApplyFilter(bitmap); // get destination dimensions int width, height; bool shouldContinue = GetDestinationDimensions(bitmap, out width, out height); if (!shouldContinue) { return; } DrawingVisual dv = new DrawingVisual(); ConfigureDrawingVisual(bitmap, dv); DrawingContext dc = dv.RenderOpen(); ApplyFilter(bitmap, dc, width, height); dc.Close(); RenderTargetBitmap rtb = RenderTargetBitmapUtility.CreateRenderTargetBitmap(width, height); rtb.Render(dv); FastBitmap destination = new FastBitmap(rtb); // copy metadata // TODO /*foreach (PropertyItem propertyItem in bitmap.InnerBitmap.PropertyItems) * destination.InnerBitmap.SetPropertyItem(propertyItem);*/ // set new image bitmap.InnerBitmap = destination.InnerBitmap; OnEndApplyFilter(); }
private BitmapSource CreateImage() { ValidateParameters(); // First, we process layers which have a specific size. foreach (Layer layer in VisibleLayers) { if (layer.HasFixedSize) { layer.Process(); } } // Second, for SizeMode = Auto, we calculate the output dimensions // based on the union of all layers' (which have an explicit size) dimensions. int outputWidth, outputHeight; if (AutoSize) { Int32Rect outputDimensions = Int32Rect.Empty; foreach (Layer layer in VisibleLayers) { // Calculate dimensions of layers; the dimensions of some layers may be omitted // at design time and are then derived from layers which have a fixed size. // Only include layer in bounds calculation if the Anchor property is None. if (layer.Anchor == AnchorStyles.None) { Int32Rect?bounds = layer.Bounds; if (bounds != null) { outputDimensions = Int32RectUtility.Union(outputDimensions, bounds.Value); } } } outputWidth = outputDimensions.Width; outputHeight = outputDimensions.Height; } else { outputWidth = Width.Value; outputHeight = Height.Value; } // If at this point we don't have a valid size, return - this means that // layers without an explicit size will never force an image to be created. if (outputWidth == 0 && outputHeight == 0) { return(null); } // Second, layers which don't have explicit sizes set, we now set their sizes // based on the overall composition size, and process the layer. foreach (Layer layer in this.VisibleLayers) { if (!layer.HasFixedSize) { layer.CalculatedWidth = outputWidth; layer.CalculatedHeight = outputHeight; layer.Process(); } } // If any of the layers are not present, we don't create the image foreach (Layer layer in this.VisibleLayers) { if (layer.Bitmap == null) { return(null); } } // Calculate X and Y for layers which are anchored. foreach (Layer layer in this.VisibleLayers) { if (layer.Bitmap != null && layer.Anchor != AnchorStyles.None) { // Set X. switch (layer.Anchor) { case AnchorStyles.BottomCenter: case AnchorStyles.MiddleCenter: case AnchorStyles.TopCenter: layer.X = (outputWidth - layer.Size.Value.Width) / 2; break; case AnchorStyles.BottomLeft: case AnchorStyles.MiddleLeft: case AnchorStyles.TopLeft: layer.X = layer.AnchorPadding; break; case AnchorStyles.BottomRight: case AnchorStyles.MiddleRight: case AnchorStyles.TopRight: layer.X = outputWidth - layer.Size.Value.Width - layer.AnchorPadding; break; } // Set Y. switch (layer.Anchor) { case AnchorStyles.BottomCenter: case AnchorStyles.BottomLeft: case AnchorStyles.BottomRight: layer.Y = outputHeight - layer.Size.Value.Height - layer.AnchorPadding; break; case AnchorStyles.MiddleCenter: case AnchorStyles.MiddleLeft: case AnchorStyles.MiddleRight: layer.Y = (outputHeight - layer.Size.Value.Height) / 2; break; case AnchorStyles.TopCenter: case AnchorStyles.TopLeft: case AnchorStyles.TopRight: layer.Y = layer.AnchorPadding; break; } } } // Apply fill. DrawingVisual dv = new DrawingVisual(); DrawingContext dc = dv.RenderOpen(); // Apply fill. Fill.Apply(dc, new Rect(0, 0, outputWidth, outputHeight)); dc.Close(); // create output bitmap and lock data RenderTargetBitmap rtb = RenderTargetBitmapUtility.CreateRenderTargetBitmap(outputWidth, outputHeight); rtb.Render(dv); FastBitmap output = new FastBitmap(rtb); // Blend layers using specified blend mode. output = LayerBlender.BlendLayers(output, VisibleLayers); // Apply global filters. foreach (Filter filter in Filters) { if (filter.Enabled) { filter.ApplyFilter(output); } } // If image format doesn't support transparency, make all transparent pixels totally opaque. // Otherwise WPF wants to save them as black. if (ImageFormat == DynamicImageFormat.Bmp || ImageFormat == DynamicImageFormat.Jpeg) { output.Lock(); for (int y = 0; y < output.Height; ++y) { for (int x = 0; x < output.Width; ++x) { Color c = output[x, y]; //if (output[x, y].A == 0 && output[x, y].R == 0 && output[x, y].G == 0 && output[x, y].B == 0) output[x, y] = Color.FromArgb(255, c.R, c.G, c.B); } } output.Unlock(); } // Freeze the bitmap - this means any thread can access it, as well // as perhaps providing some performance benefit. output.InnerBitmap.Freeze(); return(output.InnerBitmap); }