Browse Source

#278 Support more export formats.
Also import formats extended.

tomaszkot 3 years ago
parent
commit
76ac566ba1

+ 80 - 0
PixiEditor/Helpers/SupportedFilesHelper.cs

@@ -0,0 +1,80 @@
+using PixiEditor.Models;
+using System;
+using System.Collections.Generic;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+
+
+namespace PixiEditor.Helpers
+{
+    internal class SupportedFilesHelper
+    {
+        static ImageFormat[] _imageFormats = new[] { ImageFormat.Png, ImageFormat.Jpeg, ImageFormat.Bmp, ImageFormat.Gif, /*ImageFormat.Tiff */};
+        static Dictionary<string, List<string>> extensions;
+        public static ImageFormat[] ImageFormats { get => _imageFormats; }
+
+        static SupportedFilesHelper()
+        {
+            extensions = new Dictionary<string, List<string>>();
+            extensions[Constants.NativeExtension] = new List<string>() { Constants.NativeExtension };
+            foreach(var format in _imageFormats)
+                extensions[Format2Extension(format)] = GetExtensions(format);
+        }
+
+        public static IEnumerable<string> GetSupportedExtensions()
+        {
+            return extensions.SelectMany(i => i.Value);
+        }
+
+        public static List<string> GetExtensions(ImageFormat format)
+        {
+            var res = new List<string>();
+            res.Add(Format2Extension(format));
+            if (format == ImageFormat.Jpeg)
+                res.Add(".jpg");
+            return res;
+        }
+
+        private static string Format2Extension(ImageFormat format)
+        {
+            return "." + format.ToString().ToLower();
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="imageFormat">ImageFormat</param>
+        /// <returns>Extensions of the image e.g. *.jpg;*.jpeg</returns>
+        public static string GetExtensionsFormattedForDialog(ImageFormat imageFormat)
+        {
+            var parts = GetExtensions(imageFormat);
+            return GetExtensionsFormattedForDialog(parts);
+        }
+
+        public static string GetExtensionsFormattedForDialog(IEnumerable<string> parts)
+        {
+            return string.Join(";", parts.Select(i => "*" + i));
+        }
+
+        public static bool IsSupportedFile(string path)
+        {
+            var ext = Path.GetExtension(path.ToLower());
+            return GetSupportedExtensions().Contains(ext);
+        }
+
+        public static bool IsExtensionSupported(string fileExtension)
+        {
+            return GetSupportedExtensions().Contains(fileExtension);
+        }
+
+        public static string GetFormattedFilesExtensions(bool includePixi)
+        {
+            var allExts = SupportedFilesHelper.GetSupportedExtensions().ToList();
+            if (!includePixi)
+                allExts.Remove(Constants.NativeExtension);
+            var imageFilesExts = SupportedFilesHelper.GetExtensionsFormattedForDialog(allExts);
+            return imageFilesExts;
+        }
+    }
+}

+ 5 - 5
PixiEditor/Models/DataHolders/RecentlyOpenedDocument.cs

@@ -43,11 +43,8 @@ namespace PixiEditor.Models.DataHolders
                 {
                     return "? (Corrupt)";
                 }
-
                 string extension = Path.GetExtension(filePath).ToLower();
-                return extension is not (".pixi" or ".png" or ".jpg" or ".jpeg")
-                    ? $"? ({extension})"
-                    : extension;
+                return SupportedFilesHelper.IsExtensionSupported(extension) ? extension : $"? ({extension})";
             }
         }
 
@@ -93,7 +90,7 @@ namespace PixiEditor.Models.DataHolders
 
                 return surface.ToWriteableBitmap();
             }
-            else if (FileExtension is ".png" or ".jpg" or ".jpeg")
+            else if (SupportedFilesHelper.IsExtensionSupported(FileExtension))
             {
                 WriteableBitmap bitmap = null;
 
@@ -115,6 +112,9 @@ namespace PixiEditor.Models.DataHolders
                     MaxAllowedHeightInPixels = Constants.MaxPreviewHeight,
                 };
 
+                if (bitmap == null)
+                    return null;
+
                 return imageFileMaxSizeChecker.IsFileUnderMaxSize(bitmap) ?
                     bitmap
                     : bitmap.Resize(width: Constants.MaxPreviewWidth, height: Constants.MaxPreviewHeight, WriteableBitmapExtensions.Interpolation.Bilinear);

+ 18 - 12
PixiEditor/Models/IO/Exporter.cs

@@ -1,4 +1,5 @@
 using Microsoft.Win32;
+using PixiEditor.Helpers;
 using PixiEditor.Helpers.Extensions;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Dialogs;
@@ -18,8 +19,6 @@ namespace PixiEditor.Models.IO
 {
     public class Exporter
     {
-        static ImageFormat[] _formats = new[] { ImageFormat.Png, ImageFormat.Jpeg, ImageFormat.Bmp, ImageFormat.Gif, ImageFormat.Tiff };
-        
         /// <summary>
         ///     Saves document as .pixi file that contains all document data.
         /// </summary>
@@ -27,10 +26,10 @@ namespace PixiEditor.Models.IO
         /// <param name="path">Path where file was saved.</param>
         public static bool SaveAsEditableFileWithDialog(Document document, out string path)
         {
-            var pixi = GetFormattedString("PixiEditor File", Constants.NativeExtensionNoDot);
+            
             SaveFileDialog dialog = new SaveFileDialog
             {
-                Filter = pixi + "|" + BuildFilter(),
+                Filter = BuildFilter(true),
                 FilterIndex = 0
             };
             if ((bool)dialog.ShowDialog())
@@ -43,21 +42,29 @@ namespace PixiEditor.Models.IO
             return false;
         }
 
-        public static string BuildFilter()
+        public static string BuildFilter(bool includePixi)
         {
-          var filter = string.Join("|", Formats.Select(i => GetFormattedString(i)));
+          string filter = string.Empty;
+          if(includePixi)
+            filter += GetFormattedString("PixiEditor Files", Constants.NativeExtensionNoDot) + "|";
+          filter += string.Join("|", SupportedFilesHelper.ImageFormats.Select(i => GetFormattedString(i)));
           return filter;
         }
 
         public static string GetFormattedString(ImageFormat imageFormat)
         {
-            var formatLower = imageFormat.ToString().ToLower();
-            return GetFormattedString(imageFormat.ToString() + " Image", formatLower);
+            return GetFormattedString(imageFormat.ToString() + " Images", SupportedFilesHelper.GetExtensionsFormattedForDialog(imageFormat));
         }
 
-        private static string GetFormattedString(string imageFormat, string formatLower)
+        /// <summary>
+        /// Returns formatted line describing image
+        /// </summary>
+        /// <param name="imageFormatDisplayName">Human name like 'PNG Images' </param>
+        /// <param name="extensions">Extensions of the image e.g. (*.jpg;*.jpeg)</param>
+        /// <returns>Description of the image kind, e.g. PNG Images (*.png)</returns>
+        private static string GetFormattedString(string imageFormatDisplayName, string extensions)
         {
-            return $"{imageFormat}|*.{formatLower}";
+            return $"{imageFormatDisplayName}|{extensions}";
         }
 
         /// <summary>
@@ -90,11 +97,10 @@ namespace PixiEditor.Models.IO
                     .GetValue(null);
         }
 
-        //static Dictionary<ImageFormat, Action<ExportFileDialog, WriteableBitmap>> encoders = new Dictionary<ImageFormat, Action<ExportFileDialog, WriteableBitmap>>();
         //TODO remove static methods/members
         static Dictionary<ImageFormat, Func<BitmapEncoder>> encodersFactory = new Dictionary<ImageFormat, Func<BitmapEncoder>>();
 
-        public static ImageFormat[] Formats { get => _formats; }
+        
 
         static Exporter()
         {

+ 2 - 2
PixiEditor/Models/IO/Importer.cs

@@ -7,6 +7,7 @@ using SkiaSharp;
 using System;
 using System.IO;
 using System.IO.Compression;
+using System.Linq;
 using System.Runtime.InteropServices;
 using System.Windows.Media.Imaging;
 
@@ -87,8 +88,7 @@ namespace PixiEditor.Models.IO
 
         public static bool IsSupportedFile(string path)
         {
-            path = path.ToLower();
-            return path.EndsWith(".pixi") || path.EndsWith(".png") || path.EndsWith(".jpg") || path.EndsWith(".jpeg");
+            return SupportedFilesHelper.IsSupportedFile(path);
         }
 
         public static Surface LoadFromGZippedBytes(string path)

+ 3 - 2
PixiEditor/ViewModels/ImportFilePopupViewModel.cs

@@ -1,5 +1,6 @@
 using PixiEditor.Exceptions;
 using PixiEditor.Helpers;
+using PixiEditor.Models.IO;
 using System;
 using System.IO;
 using System.Windows;
@@ -69,12 +70,12 @@ namespace PixiEditor.ViewModels
 
         private void CheckForPath(string path)
         {
-            if (File.Exists(path) && (path.EndsWith(".png") || path.EndsWith(".jpeg") || path.EndsWith(".jpg")))
+            if (SupportedFilesHelper.IsSupportedFile(path))
             {
                 try
                 {
                     filePath = path;
-                    BitmapImage bitmap = new BitmapImage(new Uri(path));
+                    var bitmap = new BitmapImage(new Uri(path));
                     ImportHeight = bitmap.PixelHeight;
                     ImportWidth = bitmap.PixelWidth;
                 }

+ 2 - 2
PixiEditor/ViewModels/SaveFilePopupViewModel.cs

@@ -61,8 +61,8 @@ namespace PixiEditor.ViewModels
             {
                 Title = "Export path",
                 CheckPathExists = true,
-                DefaultExt = "." + Exporter.Formats.First().ToString().ToLower(),
-                Filter = Exporter.BuildFilter()
+                DefaultExt = "." + SupportedFilesHelper.ImageFormats.First().ToString().ToLower(),
+                Filter = Exporter.BuildFilter(false)
             };
             if (path.ShowDialog() == true)
             {

+ 9 - 6
PixiEditor/ViewModels/SubViewModels/Main/FileViewModel.cs

@@ -2,6 +2,7 @@
 using Newtonsoft.Json.Linq;
 using PixiEditor.Exceptions;
 using PixiEditor.Helpers;
+using PixiEditor.Models;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Dialogs;
 using PixiEditor.Models.IO;
@@ -10,6 +11,7 @@ using PixiEditor.Parser;
 using PixiEditor.Views.Dialogs;
 using System;
 using System.Collections.Generic;
+using System.Drawing.Imaging;
 using System.IO;
 using System.Linq;
 using System.Windows;
@@ -199,16 +201,17 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
                 }
             }
         }
-
+                
         private void Open(object property)
         {
+            var filter = 
+                "Any |" + SupportedFilesHelper.GetFormattedFilesExtensions(true) + "|" + 
+                "PixiEditor Files |" + SupportedFilesHelper.GetExtensionsFormattedForDialog(new[] { Constants.NativeExtension }) + "|" +
+                "Image Files |" + SupportedFilesHelper.GetFormattedFilesExtensions(false);
             OpenFileDialog dialog = new OpenFileDialog
             {
-                Filter =
-                "Any|*.pixi;*.png;*.jpg;*.jpeg;|" +
-                "PixiEditor Files | *.pixi|" +
-                "Image Files|*.png;*.jpg;*.jpeg;",
-                DefaultExt = "pixi"
+                Filter = filter,
+                FilterIndex = 0
             };
 
             if ((bool)dialog.ShowDialog())

+ 2 - 1
PixiEditor/Views/UserControls/Layers/ReferenceLayer.xaml.cs

@@ -1,4 +1,5 @@
 using Microsoft.Win32;
+using PixiEditor.Helpers;
 using PixiEditor.Models.IO;
 using PixiEditor.Models.Layers;
 using System;
@@ -56,7 +57,7 @@ namespace PixiEditor.Views.UserControls.Layers
             {
                 Title = "Reference layer path",
                 CheckPathExists = true,
-                Filter = "Image Files|*.png;*.jpeg;*.jpg|PNG Files|*.png|JPG Files|*.jpeg;*.jpg"
+                Filter = "Image Files | " + SupportedFilesHelper.GetFormattedFilesExtensions(false)
             };
 
             return (bool)dialog.ShowDialog() ? dialog.FileName : null;

+ 2 - 0
PixiEditorTests/ModelsTests/IO/ImporterTests.cs

@@ -26,6 +26,8 @@ namespace PixiEditorTests.ModelsTests.IO
         [InlineData("dub.jpeg")]
         [InlineData("-.JPEG")]
         [InlineData("dub.jpg")]
+        [InlineData("dub.gif")]
+        [InlineData("dub.bmp")]
         public void TestThatIsSupportedFile(string file)
         {
             Assert.True(Importer.IsSupportedFile(file));