public static Surface CombineLayers(Int32Rect portion, IEnumerable <Layer> layers, LayerStructure structure = null) { Surface finalSurface = new(portion.Width, portion.Height); using SKPaint paint = new(); for (int i = 0; i < layers.Count(); i++) { Layer layer = layers.ElementAt(i); if (structure != null && !LayerStructureUtils.GetFinalLayerIsVisible(layer, structure)) { continue; } float layerOpacity = structure == null ? layer.Opacity : LayerStructureUtils.GetFinalLayerOpacity(layer, structure); paint.Color = new(255, 255, 255, (byte)(layerOpacity * 255)); if (layer.OffsetX < 0 || layer.OffsetY < 0 || layer.Width + layer.OffsetX > layer.MaxWidth || layer.Height + layer.OffsetY > layer.MaxHeight) { throw new InvalidOperationException("Layers must not extend beyond canvas borders"); } using SKImage snapshot = layer.LayerBitmap.SkiaSurface.Snapshot(); int x = portion.X - layer.OffsetX; int y = portion.Y - layer.OffsetY; finalSurface.SkiaSurface.Canvas.DrawImage( snapshot, new SKRect(x, y, portion.Width + x, portion.Height + y), new SKRect(0, 0, portion.Width, portion.Height), paint); } return(finalSurface); }
/// <summary> /// Converts layers bitmaps into one bitmap. /// </summary> /// <param name="width">Width of final bitmap.</param> /// <param name="height">Height of final bitmap.</param>. /// <param name="layers">Layers to combine.</param> /// <returns>WriteableBitmap of layered bitmaps.</returns> public static WriteableBitmap CombineLayers(int width, int height, IEnumerable <Layer> layers, LayerStructure structure = null) { WriteableBitmap finalBitmap = BitmapFactory.New(width, height); using (finalBitmap.GetBitmapContext()) { for (int i = 0; i < layers.Count(); i++) { Layer layer = layers.ElementAt(i); float layerOpacity = structure == null ? layer.Opacity : LayerStructureUtils.GetFinalLayerOpacity(layer, structure); if (layer.OffsetX < 0 || layer.OffsetY < 0 || layer.Width + layer.OffsetX > layer.MaxWidth || layer.Height + layer.OffsetY > layer.MaxHeight) { throw new InvalidOperationException("Layers must not extend beyond canvas borders"); } for (int y = 0; y < layer.Height; y++) { for (int x = 0; x < layer.Width; x++) { Color previousColor = finalBitmap.GetPixel(x + layer.OffsetX, y + layer.OffsetY); Color color = layer.GetPixel(x, y); finalBitmap.SetPixel(x + layer.OffsetX, y + layer.OffsetY, BlendColor(previousColor, color, layerOpacity)); } } } } return(finalBitmap); }
public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Length > 0 && values[0] is Layer layer && ViewModelMain.Current?.BitmapManager?.ActiveDocument != null) { return((double)LayerStructureUtils.GetFinalLayerOpacity(layer, ViewModelMain.Current.BitmapManager.ActiveDocument.LayerStructure)); } return(null); }