Selaa lähdekoodia

Update more things

Equbuxu 4 vuotta sitten
vanhempi
commit
9d1e527508

+ 1 - 2
PixiEditor/Helpers/Extensions/ParserHelpers.cs

@@ -1,5 +1,4 @@
 using PixiEditor.Models.DataHolders;
-using PixiEditor.Models.ImageManipulation;
 using PixiEditor.Models.Layers;
 using PixiEditor.Parser;
 using PixiEditor.Parser.Models;
@@ -45,7 +44,7 @@ namespace PixiEditor.Helpers.Extensions
             {
                 Parser.SerializableLayer serLayer = serializableDocument.Layers[i];
                 Layer layer =
-                    new Layer(serLayer.Name, BitmapUtils.BytesToWriteableBitmap(serLayer.Width, serLayer.Height, serLayer.BitmapBytes))
+                    new Layer(serLayer.Name, new Surface(serLayer.Width, serLayer.Height, serLayer.BitmapBytes))
                     {
                         IsVisible = serLayer.IsVisible,
                         Offset = new Thickness(serLayer.OffsetX, serLayer.OffsetY, 0, 0),

+ 1 - 1
PixiEditor/Helpers/LayerBitmapContext.cs

@@ -18,7 +18,7 @@ namespace PixiEditor.Helpers
         public LayerBitmapContext(Layer layer)
         {
             this.layer = layer;
-            ctx = layer.LayerBitmap.GetBitmapContext();
+            //ctx = layer.LayerBitmap.GetBitmapContext();
         }
 
         public void Dispose() => ctx.Dispose();

+ 11 - 13
PixiEditor/Models/Controllers/BitmapOperationsUtility.cs

@@ -1,11 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using PixiEditor.Helpers.Extensions;
+using PixiEditor.Helpers.Extensions;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.ImageManipulation;
 using PixiEditor.Models.Layers;
@@ -13,7 +6,11 @@ using PixiEditor.Models.Position;
 using PixiEditor.Models.Tools;
 using PixiEditor.Models.Tools.ToolSettings.Settings;
 using PixiEditor.Models.Undo;
-using PixiEditor.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Input;
+using System.Windows.Media;
 
 namespace PixiEditor.Models.Controllers
 {
@@ -120,7 +117,7 @@ namespace PixiEditor.Models.Controllers
 
         private void UseTool(List<Coordinates> mouseMoveCords, BitmapOperationTool tool, Color color)
         {
-            if(sizeSetting == null)
+            if (sizeSetting == null)
             {
                 sizeSetting = tool.Toolbar.GetSetting<SizeSetting>("ToolSize");
             }
@@ -242,14 +239,15 @@ namespace PixiEditor.Models.Controllers
         private BitmapPixelChanges GetOldPixelsValues(Coordinates[] coordinates)
         {
             Dictionary<Coordinates, Color> values = new Dictionary<Coordinates, Color>();
-            using (Manager.ActiveLayer.LayerBitmap.GetBitmapContext(ReadWriteMode.ReadOnly))
+            //using (Manager.ActiveLayer.LayerBitmap.GetBitmapContext(ReadWriteMode.ReadOnly))
             {
                 Coordinates[] relativeCoords = Manager.ActiveLayer.ConvertToRelativeCoordinates(coordinates);
                 for (int i = 0; i < coordinates.Length; i++)
                 {
+                    var cl = Manager.ActiveLayer.GetPixel(relativeCoords[i].X, relativeCoords[i].Y);
                     values.Add(
                         coordinates[i],
-                        Manager.ActiveLayer.GetPixel(relativeCoords[i].X, relativeCoords[i].Y));
+                        Color.FromArgb(cl.Alpha, cl.Red, cl.Green, cl.Blue));
                 }
             }
 
@@ -300,4 +298,4 @@ namespace PixiEditor.Models.Controllers
             }
         }
     }
-}
+}

+ 50 - 11
PixiEditor/Models/DataHolders/Surface.cs

@@ -1,14 +1,18 @@
 using SkiaSharp;
 using System;
+using System.Runtime.InteropServices;
+using System.Windows;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
 
 namespace PixiEditor.Models.DataHolders
 {
-    public class Surface
+    public class Surface : IDisposable
     {
         public static SKPaint ReplacingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.Src };
         private static readonly SKPaint nearestNeighborReplacingPaint = new SKPaint() { BlendMode = SKBlendMode.Src, FilterQuality = SKFilterQuality.Low };
 
-        public SKSurface SKSurface { get; }
+        public SKSurface SkiaSurface { get; }
         public int Width { get; }
         public int Height { get; }
 
@@ -16,7 +20,7 @@ namespace PixiEditor.Models.DataHolders
 
         public Surface(int w, int h)
         {
-            SKSurface = CreateSurface(w, h);
+            SkiaSurface = CreateSurface(w, h);
             Width = w;
             Height = h;
         }
@@ -26,15 +30,34 @@ namespace PixiEditor.Models.DataHolders
             Width = original.Width;
             Height = original.Height;
             var newSurface = CreateSurface(Width, Height);
-            original.SKSurface.Draw(newSurface.Canvas, 0, 0, ReplacingPaint);
-            SKSurface = newSurface;
+            original.SkiaSurface.Draw(newSurface.Canvas, 0, 0, ReplacingPaint);
+            SkiaSurface = newSurface;
+        }
+
+        public Surface(int w, int h, byte[] pbgra32Bytes)
+        {
+            SKImageInfo info = new SKImageInfo(w, h, SKColorType.Bgra8888, SKAlphaType.Premul);
+            var ptr = Marshal.AllocHGlobal(pbgra32Bytes.Length);
+            try
+            {
+                Marshal.Copy(pbgra32Bytes, 0, ptr, pbgra32Bytes.Length);
+                SKPixmap map = new(info, ptr);
+                SKSurface surface = SKSurface.Create(map);
+                var newSurface = CreateSurface(w, h);
+                surface.Draw(newSurface.Canvas, 0, 0, ReplacingPaint);
+                SkiaSurface = newSurface;
+            }
+            finally
+            {
+                Marshal.FreeHGlobal(ptr);
+            }
         }
 
         public Surface ResizeNearestNeighbor(int newW, int newH)
         {
-            SKImage image = SKSurface.Snapshot();
+            SKImage image = SkiaSurface.Snapshot();
             Surface newSurface = new(newW, newH);
-            newSurface.SKSurface.Canvas.DrawImage(image, new SKRect(0, 0, newW, newH), nearestNeighborReplacingPaint);
+            newSurface.SkiaSurface.Canvas.DrawImage(image, new SKRect(0, 0, newW, newH), nearestNeighborReplacingPaint);
             return newSurface;
         }
 
@@ -46,27 +69,43 @@ namespace PixiEditor.Models.DataHolders
             var imageInfo = new SKImageInfo(1, 1, SKColorType.Bgra8888, SKAlphaType.Premul);
             using SKBitmap bitmap = new SKBitmap(imageInfo);
             IntPtr dstpixels = bitmap.GetPixels();
-            SKSurface.ReadPixels(imageInfo, dstpixels, imageInfo.RowBytes, x, y);
+            SkiaSurface.ReadPixels(imageInfo, dstpixels, imageInfo.RowBytes, x, y);
             return bitmap.GetPixel(0, 0);
         }
 
         public void SetSRGBPixel(int x, int y, SKColor color)
         {
             drawingPaint.Color = color;
-            SKSurface.Canvas.DrawPoint(x, y, drawingPaint);
+            SkiaSurface.Canvas.DrawPoint(x, y, drawingPaint);
         }
 
         /// <summary>
         /// probably doesn't work correctly
         /// </summary>
-        public byte[] ToSRGBByteArray()
+        public byte[] ToPbgra32ByteArray()
+        {
+            return SkiaSurface.Snapshot().Encode(SKEncodedImageFormat.Bmp, 100).ToArray();
+        }
+
+        public WriteableBitmap ToWriteableBitmap()
         {
-            return SKSurface.Snapshot().Encode(SKEncodedImageFormat.Bmp, 100).ToArray();
+            WriteableBitmap result = new WriteableBitmap(Width, Height, 96, 96, PixelFormats.Pbgra32, null);
+            result.Lock();
+            result.CopyPixels(ToPbgra32ByteArray(), Width * 4, 0);
+            result.AddDirtyRect(new Int32Rect(0, 0, Width, Height));
+            result.Unlock();
+            return result;
+        }
+
+        public void Dispose()
+        {
+            SkiaSurface.Dispose();
         }
 
         private static SKSurface CreateSurface(int w, int h)
         {
             return SKSurface.Create(new SKImageInfo(0, 0, SKColorType.RgbaF16, SKAlphaType.Premul, SKColorSpace.CreateSrgb()));
         }
+
     }
 }

+ 32 - 42
PixiEditor/Models/ImageManipulation/BitmapUtils.cs

@@ -3,11 +3,11 @@ using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers.Utils;
 using PixiEditor.Models.Position;
 using PixiEditor.Parser;
+using SkiaSharp;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Runtime.CompilerServices;
-using System.Windows;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 
@@ -40,51 +40,41 @@ namespace PixiEditor.Models.ImageManipulation
         /// <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)
+        public static Surface CombineLayers(int width, int height, IEnumerable<Layer> layers, LayerStructure structure = null)
         {
-            WriteableBitmap finalBitmap = BitmapFactory.New(width, height);
+            Surface finalSurface = new(width, height);
+            using SKPaint paint = new();
 
-            using (finalBitmap.GetBitmapContext())
+            for (int i = 0; i < layers.Count(); i++)
             {
-                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");
-                    }
+                Layer layer = layers.ElementAt(i);
+                float layerOpacity = structure == null ? layer.Opacity : LayerStructureUtils.GetFinalLayerOpacity(layer, structure);
+                paint.Color = new(255, 255, 255, (byte)(layerOpacity * 255));
 
-                    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));
-                        }
-                    }
+                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");
                 }
+
+                layer.LayerBitmap.SkiaSurface.Draw(finalSurface.SkiaSurface.Canvas, layer.OffsetX, layer.OffsetY, paint);
             }
 
-            return finalBitmap;
+            return finalSurface;
         }
 
         public static Color GetColorAtPointCombined(int x, int y, params Layer[] layers)
         {
             Color prevColor = Color.FromArgb(0, 0, 0, 0);
-
+            /*
             for (int i = 0; i < layers.Length; i++)
             {
                 Color color = layers[i].GetPixelWithOffset(x, y);
                 float layerOpacity = layers[i].Opacity;
 
                 prevColor = BlendColor(prevColor, color, layerOpacity);
-            }
+            }*/
 
             return prevColor;
         }
@@ -129,7 +119,7 @@ namespace PixiEditor.Models.ImageManipulation
             var opacityLayers = layers.Where(x => x.IsVisible && x.Opacity > 0.8f);
 
             return GeneratePreviewBitmap(
-                opacityLayers.Select(x => BytesToWriteableBitmap(x.Width, x.Height, x.BitmapBytes)),
+                opacityLayers.Select(x => new Surface(x.Width, x.Height, x.BitmapBytes)),
                 opacityLayers.Select(x => x.OffsetX),
                 opacityLayers.Select(x => x.OffsetY),
                 width,
@@ -146,21 +136,18 @@ namespace PixiEditor.Models.ImageManipulation
             {
                 Color[] pixels = new Color[selection.Length];
 
-                using (layer.LayerBitmap.GetBitmapContext())
+                for (int j = 0; j < pixels.Length; j++)
                 {
-                    for (int j = 0; j < pixels.Length; j++)
+                    Coordinates position = layer.GetRelativePosition(selection[j]);
+                    if (position.X < 0 || position.X > layer.Width - 1 || position.Y < 0 ||
+                        position.Y > layer.Height - 1)
                     {
-                        Coordinates position = layer.GetRelativePosition(selection[j]);
-                        if (position.X < 0 || position.X > layer.Width - 1 || position.Y < 0 ||
-                            position.Y > layer.Height - 1)
-                        {
-                            continue;
-                        }
-
-                        pixels[j] = layer.GetPixel(position.X, position.Y);
+                        continue;
                     }
-                }
 
+                    var cl = layer.GetPixel(position.X, position.Y);
+                    pixels[j] = Color.FromArgb(cl.Alpha, cl.Red, cl.Green, cl.Blue);
+                }
                 result[layer.LayerGuid] = pixels;
             }
 
@@ -193,7 +180,7 @@ namespace PixiEditor.Models.ImageManipulation
         }
 
         private static WriteableBitmap GeneratePreviewBitmap(
-            IEnumerable<WriteableBitmap> layerBitmaps,
+            IEnumerable<Surface> layerBitmaps,
             IEnumerable<int> offsetsX,
             IEnumerable<int> offsetsY,
             int width,
@@ -208,6 +195,9 @@ namespace PixiEditor.Models.ImageManipulation
                 throw new ArgumentException("There were not the same amount of bitmaps and offsets", nameof(layerBitmaps));
             }
 
+            using Surface previewSurface = new Surface(maxPreviewWidth, maxPreviewHeight);
+            return previewSurface.ToWriteableBitmap();
+            /*
             WriteableBitmap previewBitmap = BitmapFactory.New(width, height);
 
             var layerBitmapsEnumerator = layerBitmaps.GetEnumerator();
@@ -231,7 +221,7 @@ namespace PixiEditor.Models.ImageManipulation
 
             int newWidth = width >= height ? maxPreviewWidth : (int)Math.Ceiling(width / ((float)height / maxPreviewHeight));
             int newHeight = height > width ? maxPreviewHeight : (int)Math.Ceiling(height / ((float)width / maxPreviewWidth));
-            return previewBitmap.Resize(newWidth, newHeight, WriteableBitmapExtensions.Interpolation.NearestNeighbor);
+            return previewBitmap.Resize(newWidth, newHeight, WriteableBitmapExtensions.Interpolation.NearestNeighbor);*/
         }
     }
 }

+ 3 - 3
PixiEditor/Models/Layers/Layer.cs

@@ -418,7 +418,7 @@ namespace PixiEditor.Models.Layers
         /// </summary>
         public void Clear()
         {
-            LayerBitmap.SKSurface.Canvas.Clear();
+            LayerBitmap.SkiaSurface.Canvas.Clear();
             ClipCanvas();
         }
 
@@ -427,7 +427,7 @@ namespace PixiEditor.Models.Layers
         /// </summary>
         public byte[] ConvertBitmapToBytes()
         {
-            return LayerBitmap.ToSRGBByteArray();
+            return LayerBitmap.ToPbgra32ByteArray();
         }
 
         private Dictionary<Coordinates, Color> GetRelativePosition(Dictionary<Coordinates, Color> changedPixels)
@@ -557,7 +557,7 @@ namespace PixiEditor.Models.Layers
 
             Surface result = new Surface(newWidth, newHeight);
 
-            LayerBitmap.SKSurface.Draw(result.SKSurface.Canvas, offsetX - offsetXSrc, offsetY - offsetYSrc, Surface.ReplacingPaint);
+            LayerBitmap.SkiaSurface.Draw(result.SkiaSurface.Canvas, offsetX - offsetXSrc, offsetY - offsetYSrc, Surface.ReplacingPaint);
             /*for (int line = 0; line < iteratorHeight; line++)
             {
                 int srcOff = (((offsetYSrc + line) * Width) + offsetXSrc) * SizeOfArgb;