diff --git a/FB2Library/Elements/BinaryItem.cs b/FB2Library/Elements/BinaryItem.cs index 6517d3c..699bd3b 100644 --- a/FB2Library/Elements/BinaryItem.cs +++ b/FB2Library/Elements/BinaryItem.cs @@ -16,28 +16,28 @@ public class BinaryItem private const string ContentTypeAttributeName = "content-type"; private const string IdAttributeName = "id"; - public ContentTypeEnum ContentType{get;set;} - public Byte[] BinaryData { get; set; } - public string Id { get; set; } - + internal const string Fb2BinaryItemName = "binary"; + public static Func DetectContentType { get; set; } - internal const string Fb2BinaryItemName = "binary"; + public ContentTypeEnum ContentType { get; set; } + public byte[] BinaryData { get; set; } + public string Id { get; set; } internal void Load(XElement binarye) { if (binarye == null) { - throw new ArgumentNullException("binarye"); + throw new ArgumentNullException(nameof(binarye)); } if (binarye.Name.LocalName != Fb2BinaryItemName) { - throw new ArgumentException("Element of wrong type passed", "binarye"); + throw new ArgumentException("Element of wrong type passed", nameof(binarye)); } XAttribute xContentType = binarye.Attribute(ContentTypeAttributeName); - if ((xContentType == null) || (xContentType.Value == null)) + if (xContentType?.Value == null) { throw new NullReferenceException("content type not defined/present"); } @@ -58,59 +58,35 @@ internal void Load(XElement binarye) } XAttribute idAttribute = binarye.Attribute(IdAttributeName); - if ((idAttribute == null) || (idAttribute.Value == null)) - { - throw new NullReferenceException("ID not defined/present"); - } - Id = idAttribute.Value; + + Id = idAttribute?.Value ?? throw new NullReferenceException("ID not defined/present"); if (BinaryData != null) { - BinaryData= null; + BinaryData = null; } BinaryData = Convert.FromBase64String(binarye.Value); - //ContentTypeEnum content; - // try to detect type , this will detect for unknown and fix for wrongly set - //DetectContentType(out content, BinaryData); - // if we were not able to detect type and type was not set - //if (content == ContentTypeEnum.ContentTypeUnknown && ContentType == ContentTypeEnum.ContentTypeUnknown) - //{ - // // then we throw exception - // throw new Exception("Unknown image content type passed"); - //} - ContentType = ContentTypeEnum.ContentTypeUnknown; // TODO + + // try to detect type, this will detect for unknown and fix for wrongly set + if (DetectContentType == null) + { + ContentType = ContentTypeEnum.ContentTypeUnknown; + } + else + { + var contentType = DetectContentType(BinaryData); + + // if we were not able to detect type and type was not set + if (contentType == ContentTypeEnum.ContentTypeUnknown + && ContentType == ContentTypeEnum.ContentTypeUnknown) + { + // then we throw exception + throw new Exception("Unknown image content type passed"); + } + + ContentType = contentType; + } } - - // private void DetectContentType(out ContentTypeEnum contentType, byte[] binaryData) - // { - // contentType = ContentTypeEnum.ContentTypeUnknown; - // try - // { - // using (MemoryStream imgStream = new MemoryStream(binaryData)) - // { - // using (Bitmap bitmap = new Bitmap(imgStream)) - // { - // if (bitmap.RawFormat.Equals(ImageFormat.Jpeg)) - // { - // contentType = ContentTypeEnum.ContentTypeJpeg; - // } - // else if (bitmap.RawFormat.Equals(ImageFormat.Png)) - // { - // contentType = ContentTypeEnum.ContentTypePng; - // } - // else if (bitmap.RawFormat.Equals(ImageFormat.Gif)) - // { - // contentType = ContentTypeEnum.ContentTypeGif; - // } - // } - //} - // } - // catch (Exception ex) - // { - // throw new Exception(string.Format("Error during image type detection: {0}",ex),ex); - // } - - // } protected string GetXContentType() { @@ -122,9 +98,9 @@ protected string GetXContentType() return "image/png"; case ContentTypeEnum.ContentTypeGif: return "image/gif"; + case ContentTypeEnum.ContentTypeUnknown: default: return ""; - } } @@ -136,7 +112,6 @@ public XElement ToXML() xBinary.Value=Convert.ToBase64String(BinaryData); return xBinary; - } } } diff --git a/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj b/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj index b706b44..2cf4206 100644 --- a/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj +++ b/FBLibrary.Sample.ConsoleApp/FBLibrary.Sample.ConsoleApp.csproj @@ -11,5 +11,10 @@ + + + + + diff --git a/FBLibrary.Sample.ConsoleApp/Program.cs b/FBLibrary.Sample.ConsoleApp/Program.cs index 73445a2..119cebc 100644 --- a/FBLibrary.Sample.ConsoleApp/Program.cs +++ b/FBLibrary.Sample.ConsoleApp/Program.cs @@ -1,5 +1,8 @@ +using System.Drawing; +using System.Drawing.Imaging; using System.Xml; using FB2Library; +using FB2Library.Elements; var filePath = Path.Combine("..", "..", "..", "..", "files", "test.fb2"); await using var fileStream = new FileStream(filePath, FileMode.Open); @@ -9,7 +12,42 @@ DtdProcessing = DtdProcessing.Ignore }; var loadSettings = new XmlLoadSettings(readerSettings); + +BinaryItem.DetectContentType = binaryData => +{ + try + { + using var imgStream = new MemoryStream(binaryData); + + // For MacOS need native libgdiplus, more: + // https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only#recommended-action +#pragma warning disable CA1416 + using var bitmap = new Bitmap(imgStream); + + var rawFormat = bitmap.RawFormat; + + if (rawFormat.Equals(ImageFormat.Jpeg)) + return ContentTypeEnum.ContentTypeJpeg; + + if (rawFormat.Equals(ImageFormat.Png)) + return ContentTypeEnum.ContentTypePng; + + if (rawFormat.Equals(ImageFormat.Gif)) + return ContentTypeEnum.ContentTypeGif; + + return ContentTypeEnum.ContentTypeUnknown; + +#pragma warning restore CA1416 + } + catch (Exception ex) + { + throw new Exception($"Error during image type detection: {ex}", ex); + } +}; + + var reader = new FB2Reader(); var file = await reader.ReadAsync(fileStream, loadSettings); + Console.WriteLine("Done"); \ No newline at end of file diff --git a/FBLibrary.Sample.ConsoleApp/runtimeconfig.template.json b/FBLibrary.Sample.ConsoleApp/runtimeconfig.template.json new file mode 100644 index 0000000..40b04a7 --- /dev/null +++ b/FBLibrary.Sample.ConsoleApp/runtimeconfig.template.json @@ -0,0 +1,5 @@ +{ + "configProperties": { + "System.Drawing.EnableUnixSupport": true + } +} \ No newline at end of file