Browse Source

Reduced individual layer size

Now layers doesn't contain Image in it, after change of layer bitmap Image refreshes with new source (bitmap). It reduced a bit size of memory usage. But still memory leak occurs
flabbet 6 years ago
parent
commit
488634919a

+ 30 - 0
PixiEditor/Models/BasicLayer.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using PixiEditor.Helpers;
+
+namespace PixiEditor.Models
+{
+    public class BasicLayer : NotifyableObject
+    {
+
+        private int _width;
+
+        public int Width
+        {
+            get { return _width; }
+            set { _width = value; RaisePropertyChanged("Width"); }
+        }
+
+        private int _height;
+
+        public int Height
+        {
+            get { return _height; }
+            set { _height = value; RaisePropertyChanged("Height"); }
+        }
+    }
+}

+ 22 - 0
PixiEditor/Models/BitmapConverter.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+
+namespace PixiEditor.Models
+{
+    public static class BitmapConverter
+    {
+        public static WriteableBitmap BytesToWriteableBitmap(int currentBitmapWidth, int currentBitmapHeight ,byte[] byteArray)
+        {
+            WriteableBitmap bitmap = BitmapFactory.New(currentBitmapWidth, currentBitmapHeight);
+            bitmap.FromByteArray(byteArray);
+            return bitmap;
+        }
+    }
+}

+ 1 - 2
PixiEditor/Models/ExColor.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Drawing;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -19,7 +18,7 @@ namespace PixiEditor.Models
         /// <returns>
         /// Corrected <see cref="Color"/> structure.
         /// </returns>
-        public static Color ChangeColorBrightness(Color color, float correctionFactor)
+        public static Color ChangeColorBrightness(System.Drawing.Color color, float correctionFactor)
         {
             float red = (float)color.R;
             float green = (float)color.G;

+ 24 - 0
PixiEditor/Models/ImageGenerator.cs

@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace PixiEditor.Models
+{
+    public static class ImageGenerator
+    {
+        public static Image GenerateForPixelArts(int width, int height)
+        {
+            Image image = new Image();
+            RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.NearestNeighbor);
+            RenderOptions.SetEdgeMode(image, EdgeMode.Aliased);
+            image.Stretch = Stretch.Uniform;
+            image.Width = width;
+            image.Height = height;
+            return image;
+        }
+    }
+}

+ 5 - 36
PixiEditor/Models/Layer.cs

@@ -13,7 +13,7 @@ using System.Windows.Media.Imaging;
 
 namespace PixiEditor.Models
 {
-    public class Layer : NotifyableObject
+    public class Layer : BasicLayer
     {
         private WriteableBitmap _layerBitmap;
 
@@ -26,51 +26,20 @@ namespace PixiEditor.Models
             }
         }
 
-        private Image _layerImage;
-
-        public Image LayerImage
-        {
-            get { return _layerImage; }
-            set {
-                _layerImage = value;
-                RaisePropertyChanged("LayerImage");
-            }
-        }
-
-        private int _width;
-
-        public int Width
-        {
-            get { return _width; }
-            set { _width = value; RaisePropertyChanged("Width"); }
-        }
-
-        private int _height;
-
-        public int Height
-        {
-            get { return _height; }
-            set { _height = value; RaisePropertyChanged("Height"); }
-        }
-
-
-
         public Layer(int width, int height)
         {
-            Layer layer = LayerGenerator.GenerateLayer(width, height);
+            Layer layer = LayerGenerator.Generate(width, height);
             LayerBitmap = layer.LayerBitmap;
-            LayerImage = layer.LayerImage;
             Width = width;
             Height = height;
         }
 
 
-        public Layer(WriteableBitmap layerBitmap, Image layerImage)
+        public Layer(WriteableBitmap layerBitmap)
         {
             LayerBitmap = layerBitmap;
-            LayerImage = layerImage;
-            Width = (int)layerImage.Width;
-            Height = (int)layerImage.Height;
+            Width = (int) layerBitmap.Width;
+            Height = (int) layerBitmap.Height;
         }
     }
 }

+ 8 - 10
PixiEditor/Models/LayerGenerator.cs

@@ -20,17 +20,15 @@ namespace PixiEditor.Models
         /// <param name="imageWidth">Width of layer.</param>
         /// <param name="imageHeight">Height of layer.</param>
         /// <returns></returns>
-        public static Layer GenerateLayer(int imageWidth, int imageHeight)
+        public static Layer Generate(int imageWidth, int imageHeight)
         {
-            Image image = new Image();
-            RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.NearestNeighbor);
-            RenderOptions.SetEdgeMode(image, EdgeMode.Aliased);
-            image.Stretch = Stretch.Uniform;
-            image.Width = imageWidth;
-            image.Height = imageHeight;
-            WriteableBitmap bitmap = GenerateBitmap(imageWidth, imageHeight);
-            image.Source = bitmap;
-            return new Layer(bitmap, image);
+            return new Layer(GenerateBitmap(imageWidth, imageHeight));
+        }
+
+        public static LightLayer GenerateWithByteArray(int width, int height)
+        {
+            WriteableBitmap bitmap = GenerateBitmap(width, height);
+            return new LightLayer(bitmap.ToByteArray(), height, width);
         }
 
         /// <summary>

+ 41 - 0
PixiEditor/Models/LightLayer.cs

@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using PixiEditor.Helpers;
+
+namespace PixiEditor.Models
+{
+    public class LightLayer : BasicLayer
+    {
+        private byte[] _layerBytes;
+
+        public byte[] LayerBytes
+        {
+            get => _layerBytes;
+            set
+            {
+                _layerBytes = value;
+                RaisePropertyChanged("LayerBytes");
+            }
+        }
+
+        public LightLayer(int width, int height)
+        {
+            LightLayer layer = LayerGenerator.GenerateWithByteArray(width, height);
+            LayerBytes = layer.LayerBytes;
+            Width = width;
+            Height = height;
+        }
+
+        public LightLayer(byte[] layerBytes, int height, int width)
+        {
+            LayerBytes = layerBytes;
+            Width = height;
+            Height = width;
+        }
+
+    }
+}

+ 7 - 9
PixiEditor/Models/Tools/ToolSet.cs

@@ -6,9 +6,9 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
+using System.Windows.Media;
 using System.Windows.Controls;
 using System.Windows.Input;
-using System.Windows.Media;
 using System.Windows.Media.Imaging;
 
 namespace PixiEditor.Models.Tools
@@ -19,7 +19,6 @@ namespace PixiEditor.Models.Tools
         private bool _toolIsExecuting = false;
         private int _asyncDelay = 15;
         private WriteableBitmap _oldBitmap;
-        private Image _oldImage;
 
         /// <summary>
         /// Executes tool action
@@ -36,8 +35,6 @@ namespace PixiEditor.Models.Tools
             Layer cLayer = layer;
 
             _oldBitmap = new WriteableBitmap(layer.LayerBitmap);
-            _oldImage = layer.LayerImage;
-            _oldImage.Source = _oldBitmap;
 
             switch (tool)
             {
@@ -78,12 +75,11 @@ namespace PixiEditor.Models.Tools
                         cLayer.LayerBitmap = Darken(cLayer.LayerBitmap, startingCoords);
                     }
                     break;
-                default:
-                    break;
             }
             if (tool != ToolType.ColorPicker)
             {
-                UndoManager.RecordChanges("ActiveLayer", new Layer(_oldBitmap, _oldImage), cLayer, string.Format("{0} Tool.", tool.ToString()));
+                UndoManager.RecordChanges("ActiveLightLayer", new LightLayer(_oldBitmap.ToByteArray(), (int)_oldBitmap.Height, (int)_oldBitmap.Width),
+                    $"{tool.ToString()} Tool.");
             }
 
             return cLayer;
@@ -305,7 +301,8 @@ namespace PixiEditor.Models.Tools
         private WriteableBitmap Lighten(WriteableBitmap bitmap, Coordinates coordinates)
         {
             WriteableBitmap wb = bitmap;
-            Color newColor = ExColor.ChangeColorBrightness(wb.GetPixel(coordinates.X, coordinates.Y), 0.1f);
+            Color pixel = wb.GetPixel(coordinates.X, coordinates.Y);
+            Color newColor = ExColor.ChangeColorBrightness(System.Drawing.Color.FromArgb(pixel.R, pixel.G, pixel.B), 0.1f);
             wb.SetPixel(coordinates.X, coordinates.Y, newColor);
             return wb;
         }
@@ -318,7 +315,8 @@ namespace PixiEditor.Models.Tools
         private WriteableBitmap Darken(WriteableBitmap bitmap, Coordinates coordinates)
         {
             WriteableBitmap wb = bitmap;
-            Color newColor = ExColor.ChangeColorBrightness(wb.GetPixel(coordinates.X, coordinates.Y), -0.06f);
+            Color pixel = wb.GetPixel(coordinates.X, coordinates.Y);
+            Color newColor = ExColor.ChangeColorBrightness(System.Drawing.Color.FromArgb(pixel.R,pixel.G,pixel.B), -0.06f);
             wb.SetPixel(coordinates.X, coordinates.Y, newColor);
             return wb;
         }

+ 7 - 6
PixiEditor/Models/UndoManager.cs

@@ -3,6 +3,7 @@ using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Diagnostics;
+using System.Drawing.Printing;
 using System.Linq;
 using System.Reflection;
 using System.Text;
@@ -53,13 +54,13 @@ namespace PixiEditor.Models
         /// <param name="oldValue">Old change value.</param>
         /// <param name="newValue">New change value.</param>
         /// <param name="undoDescription">Description of change.</param>
-        public static void RecordChanges(string property, object oldValue, object newValue, string undoDescription = null)
+        public static void RecordChanges(string property, object oldValue, string undoDescription = null)
         {
             if (_stopRecording == false)
             {
                 if (_recordedChanges.Count < 3)
                 {
-                    _recordedChanges.Add(new Change(property, oldValue, newValue, undoDescription));
+                    _recordedChanges.Add(new Change(property, oldValue, undoDescription));
                 }
             }
         }
@@ -73,7 +74,7 @@ namespace PixiEditor.Models
             if (_recordedChanges.Count > 0)
             {
                 Change changeToSave = _recordedChanges[0];
-                AddUndoChange(changeToSave.Property, changeToSave.OldValue, changeToSave.NewValue, changeToSave.Description);
+                AddUndoChange(changeToSave.Property, changeToSave.OldValue, changeToSave.Description);
                 _recordedChanges.Clear();
             }
             _stopRecording = false;
@@ -85,15 +86,15 @@ namespace PixiEditor.Models
         /// <param name="oldValue">Old value of property.</param>
         /// <param name="newValue">New value of property.</param>
         /// <param name="undoDescription">Description of change.</param>
-        public static void AddUndoChange(string property, object oldValue, object newValue, string undoDescription = null)
+        public static void AddUndoChange(string property, object oldValue, string undoDescription = null)
         {
             if(_lastChangeWasUndo == false && RedoStack.Count > 0) //Cleares RedoStack if las move wasn't redo or undo and if redo stack is greater than 0
             {
                 RedoStack.Clear();
             }
             _lastChangeWasUndo = false;
-            UndoStack.Push(new Change(property, oldValue, newValue, undoDescription)); //Adds change to UndoStack
-            if(UndoStack.Count > _stackLimit) //If Undostack hits limit, removes elements from beggining of stack
+            UndoStack.Push(new Change(property, oldValue, undoDescription)); //Adds change to UndoStack
+            if(UndoStack.Count > _stackLimit) //If Undostack hits limit, removes elements from beginning of stack
             {
                 UndoStack.Remove(0);
             }

+ 5 - 0
PixiEditor/PixiEditor.csproj

@@ -36,6 +36,7 @@
   <ItemGroup>
     <Reference Include="System" />
     <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
     <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <HintPath>packages\Expression.Blend.Sdk.1.0.2\lib\net45\System.Windows.Interactivity.dll</HintPath>
     </Reference>
@@ -85,6 +86,8 @@
     <Compile Include="Helpers\NotifyableObject.cs" />
     <Compile Include="Helpers\RelayCommand.cs" />
     <Compile Include="Helpers\ToolSizeToIntConverter.cs" />
+    <Compile Include="Models\BasicLayer.cs" />
+    <Compile Include="Models\BitmapConverter.cs" />
     <Compile Include="Models\Change.cs" />
     <Compile Include="Models\Coordinates.cs" />
     <Compile Include="Models\CustomDialog.cs" />
@@ -92,10 +95,12 @@
     <Compile Include="Models\Enums\FileType.cs" />
     <Compile Include="Models\ExColor.cs" />
     <Compile Include="Models\Exporter.cs" />
+    <Compile Include="Models\ImageGenerator.cs" />
     <Compile Include="Models\Importer.cs" />
     <Compile Include="Models\ImportFileDialog.cs" />
     <Compile Include="Models\LayerGenerator.cs" />
     <Compile Include="Models\Layer.cs" />
+    <Compile Include="Models\LightLayer.cs" />
     <Compile Include="Models\MousePositionConverter.cs" />
     <Compile Include="Models\NewFileDialog.cs" />
     <Compile Include="Models\ExportFileDialog.cs" />

+ 31 - 5
PixiEditor/ViewModels/ViewModelMain.cs

@@ -44,19 +44,43 @@ namespace PixiEditor.ViewModels
         public RelayCommand RecenterZoomboxCommand { get; set; }
         public RelayCommand OpenFileCommand { get; set; }
 
+        private Image _activeImage;
+
+        public Image ActiveImage
+        {
+            get => _activeImage;
+            set
+            {
+                _activeImage = value;
+                RaisePropertyChanged("ActiveImage");
+            }
+        }
+
         private Layer _activeLayer;
 
         public Layer ActiveLayer //Active drawing layer
         {
             get { return _activeLayer; }
             set {
-                UndoManager.AddUndoChange("ActiveLayer", _activeLayer, value, "Layer Changed");
+                if (_activeLayer != null)
+                {
+                    UndoManager.AddUndoChange("ActiveLightLayer",
+                        new LightLayer(_activeLayer.LayerBitmap.ToByteArray(), ActiveLayer.Height, ActiveLayer.Width),
+                        "Layer Changed");
+                }
+
                 _activeLayer = value;
                 RefreshImage();
                 RaisePropertyChanged("ActiveLayer");
             }
         }
 
+        public LightLayer ActiveLightLayer
+        {
+            get => new LightLayer(_activeLayer.LayerBitmap.ToByteArray(), ActiveLayer.Height, ActiveLayer.Width);
+            set => ActiveLayer = new Layer(BitmapConverter.BytesToWriteableBitmap(ActiveLayer.Width, ActiveLayer.Height,value.LayerBytes));
+        }
+
         private double _mouseXonCanvas;
 
         public double MouseXOnCanvas //Mouse X coordinate relative to canvas
@@ -231,10 +255,10 @@ namespace PixiEditor.ViewModels
 
         private void RefreshImage()
         {
-            //Jak nie będzie działać z layerami to tutaj szukaj błędu
+            //If it won't work with layers, bug might occur here
             if (ActiveLayer != null)
             {
-                Layers[0].LayerImage.Source = ActiveLayer.LayerBitmap;
+                ActiveImage.Source = ActiveLayer.LayerBitmap;
             }
         }
 
@@ -249,6 +273,7 @@ namespace PixiEditor.ViewModels
             {
                 Layers.Clear();
                 Layers.Add(new Layer(newFile.Width, newFile.Height));
+                ActiveImage = ImageGenerator.GenerateForPixelArts(newFile.Width, newFile.Height);
                 ActiveLayer = Layers[0];
             }
         }
@@ -261,11 +286,11 @@ namespace PixiEditor.ViewModels
         {
             if (Exporter._savePath == null)
             {
-                Exporter.Export(FileType.PNG, ActiveLayer.LayerImage, new Size(ActiveLayer.Width, ActiveLayer.Height));
+                Exporter.Export(FileType.PNG, ActiveImage, new Size(ActiveLayer.Width, ActiveLayer.Height));
             }
             else
             {
-                Exporter.ExportWithoutDialog(FileType.PNG, ActiveLayer.LayerImage);
+                Exporter.ExportWithoutDialog(FileType.PNG, ActiveImage);
             }
         }
         /// <summary>
@@ -290,6 +315,7 @@ namespace PixiEditor.ViewModels
             {
                 Layers.Clear();
                 Layers.Add(new Layer(dialog.FileWidth, dialog.FileHeight));
+                ActiveImage = ImageGenerator.GenerateForPixelArts(dialog.FileWidth, dialog.FileHeight);
                 ActiveLayer = Layers[0];
                 ActiveLayer.LayerBitmap = Importer.ImportImage(dialog.FilePath, dialog.FileWidth, dialog.FileHeight);
                 RefreshImage();

+ 1 - 9
PixiEditor/Views/MainWindow.xaml

@@ -127,15 +127,7 @@
                                 <behaviors:MouseBehaviour MouseX="{Binding MouseXOnCanvas, Mode=OneWayToSource}" MouseY="{Binding MouseYOnCanvas, Mode=OneWayToSource}"/>
                             </i:Interaction.Behaviors>
                             <Image Source="/Images/transparent bg.png" Height="{Binding ActiveLayer.Height}" Width="{Binding ActiveLayer.Width}" Opacity="0.2" Stretch="UniformToFill"/>
-                            <ItemsControl ItemsSource="{Binding Layers}">
-                                <ItemsControl.ItemTemplate>
-                                    <DataTemplate>
-                                        <ContentControl Content="{Binding LayerImage}"/>
-                                    </DataTemplate>
-                                </ItemsControl.ItemTemplate>
-                            </ItemsControl>
-
-
+                            <ContentControl Content="{Binding ActiveImage}"/>
                         </Canvas>
                     </vws:MainDrawingPanel.Item>
                 </vws:MainDrawingPanel>