From 129ab709ba85a58b12266aaf889474d87e167193 Mon Sep 17 00:00:00 2001 From: hueifeng <695979933@qq.com> Date: Wed, 10 Jan 2024 23:15:09 +0800 Subject: [PATCH] fix: adapt to breaking changes in SixLabors.ImageSharp --- src/EPPlus/EPPlus/Drawing/ExcelPicture.cs | 9 ++- src/EPPlus/EPPlus/ExcelBackgroundImage.cs | 14 ++++- src/EPPlus/EPPlus/ExcelHeaderFooter.cs | 21 +++++-- src/EPPlus/EPPlus/Magicodes.IE.EPPlus.csproj | 6 +- src/EPPlus/EPPlus/Utils/ImageExtensions.cs | 49 +++++++++++++++ .../Magicodes.IE.Core.csproj | 6 +- .../Images/ImageExtensions.cs | 59 +++++++++++++------ .../Utility/ImportHelper.cs | 3 +- .../TemplateExport/TemplateExportHelper.cs | 13 +++- 9 files changed, 143 insertions(+), 37 deletions(-) create mode 100644 src/EPPlus/EPPlus/Utils/ImageExtensions.cs diff --git a/src/EPPlus/EPPlus/Drawing/ExcelPicture.cs b/src/EPPlus/EPPlus/Drawing/ExcelPicture.cs index e0b4eb3b..d1791de6 100644 --- a/src/EPPlus/EPPlus/Drawing/ExcelPicture.cs +++ b/src/EPPlus/EPPlus/Drawing/ExcelPicture.cs @@ -39,6 +39,7 @@ using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Jpeg; +using Magicodes.IE.EPPlus; namespace OfficeOpenXml.Drawing { @@ -59,7 +60,9 @@ internal ExcelPicture(ExcelDrawings drawings, XmlNode node) : UriPic = UriHelper.ResolvePartUri(drawings.UriDrawing, RelPic.TargetUri); Part = drawings.Part.Package.GetPart(UriPic); - Image = Image.Load(Part.GetStream(), out var format); + // Image = Image.Load(Part.GetStream(), out var format); + Image = Image.Load(Part.GetStream()); + var format = Image.GetImageFormat(Part.GetStream()); ImageFormat = format; byte[] iby = ImageCompat.GetImageAsByteArray(Image, format); var ii = _drawings._package.LoadImage(iby, UriPic, Part); @@ -119,7 +122,9 @@ internal ExcelPicture(ExcelDrawings drawings, XmlNode node, FileInfo imageFile, var package = drawings.Worksheet._package.Package; using (var imageStream = new FileStream(imageFile.FullName, FileMode.Open, FileAccess.Read)) { - Image = Image.Load(imageStream, out var format); + // Image = Image.Load(imageStream, out var format); + Image = Image.Load(imageStream); + var format = Image.GetImageFormat(imageStream); ImageFormat = format; var img = ImageCompat.GetImageAsByteArray(Image, format); diff --git a/src/EPPlus/EPPlus/ExcelBackgroundImage.cs b/src/EPPlus/EPPlus/ExcelBackgroundImage.cs index fc56fa5a..00ee1c41 100644 --- a/src/EPPlus/EPPlus/ExcelBackgroundImage.cs +++ b/src/EPPlus/EPPlus/ExcelBackgroundImage.cs @@ -37,6 +37,7 @@ using System.Xml; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats; +using Magicodes.IE.EPPlus; namespace OfficeOpenXml { @@ -77,9 +78,14 @@ public void SetImage(byte[] imageBytes = null) DeleteAllNode(BACKGROUNDPIC_PATH); return; } + Image = Image.Load(imageBytes); + //Image = Image.Load(imageBytes, out var imageFormat); + using (MemoryStream imageStream = new MemoryStream(imageBytes)) + { + var imageFormat = Image.GetImageFormat(imageStream); + ImageFormat = imageFormat; + } - Image = Image.Load(imageBytes, out var imageFormat); - ImageFormat = imageFormat; var imageInfo = _workSheet.Workbook._package.AddImage(imageBytes); var rel = _workSheet.Part.CreateRelationship(imageInfo.Uri, Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/image"); @@ -98,7 +104,9 @@ public void SetFromFile(FileInfo pictureFile) try { var fileBytes = File.ReadAllBytes(pictureFile.FullName); - Image.Load(fileBytes, out var format); + //Image.Load(fileBytes, out var format); + var format = Image.DetectFormat(fileBytes); + string contentType = format.DefaultMimeType; var imageUri = XmlHelper.GetNewUri(_workSheet._package.Package, "/xl/media/" + diff --git a/src/EPPlus/EPPlus/ExcelHeaderFooter.cs b/src/EPPlus/EPPlus/ExcelHeaderFooter.cs index 60c4de6b..a6746f14 100644 --- a/src/EPPlus/EPPlus/ExcelHeaderFooter.cs +++ b/src/EPPlus/EPPlus/ExcelHeaderFooter.cs @@ -40,6 +40,8 @@ using System.Xml; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats; +using System.Reflection; +using Magicodes.IE.EPPlus; namespace OfficeOpenXml { @@ -150,15 +152,22 @@ public ExcelVmlDrawingPicture InsertPicture(FileInfo pictureFile, PictureAlignme { throw (new FileNotFoundException(string.Format("{0} is missing", pictureFile.FullName))); } - Picture = Image.Load(pictureFile.FullName, out var format); - string contentType = format.DefaultMimeType; - var uriPic = XmlHelper.GetNewUri(_ws._package.Package, "/xl/media/" + pictureFile.Name.Substring(0, pictureFile.Name.Length - pictureFile.Extension.Length) + "{0}" + pictureFile.Extension); - var imgBytes = ImageCompat.GetImageAsByteArray(Picture, format); + + // Picture = Image.Load(pictureFile.FullName, out var format); + Picture = Image.Load(pictureFile.FullName); + using (Stream imageStream = pictureFile.OpenRead()) + { + var format = Picture.GetImageFormat(imageStream); + string contentType = format.DefaultMimeType; + var uriPic = XmlHelper.GetNewUri(_ws._package.Package, "/xl/media/" + pictureFile.Name.Substring(0, pictureFile.Name.Length - pictureFile.Extension.Length) + "{0}" + pictureFile.Extension); + var imgBytes = ImageCompat.GetImageAsByteArray(Picture, format); - var ii = _ws.Workbook._package.AddImage(imgBytes, uriPic, contentType); + var ii = _ws.Workbook._package.AddImage(imgBytes, uriPic, contentType); - return AddImage(Picture, format, id, ii); + return AddImage(Picture, format, id, ii); + } + } catch (Exception ex) { diff --git a/src/EPPlus/EPPlus/Magicodes.IE.EPPlus.csproj b/src/EPPlus/EPPlus/Magicodes.IE.EPPlus.csproj index 25ecbc99..00f4f79a 100644 --- a/src/EPPlus/EPPlus/Magicodes.IE.EPPlus.csproj +++ b/src/EPPlus/EPPlus/Magicodes.IE.EPPlus.csproj @@ -58,19 +58,19 @@ - + - + - + diff --git a/src/EPPlus/EPPlus/Utils/ImageExtensions.cs b/src/EPPlus/EPPlus/Utils/ImageExtensions.cs new file mode 100644 index 00000000..b1108441 --- /dev/null +++ b/src/EPPlus/EPPlus/Utils/ImageExtensions.cs @@ -0,0 +1,49 @@ +using System.IO; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Formats.Bmp; +using SixLabors.ImageSharp.Formats.Gif; +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.Formats; + +namespace Magicodes.IE.EPPlus +{ + public static partial class ImageExtensions + { + public static IImageFormat GetImageFormat(this Image image, Stream imageStream) + { + var metadataProperty = image.Metadata.GetType().GetProperty("DecodedImageFormat"); + if (metadataProperty != null) + { + return metadataProperty.GetValue(image.Metadata) as IImageFormat; + } + else + { + byte[] header = new byte[4]; + long originalPosition = imageStream.Position; + + imageStream.Position = 0; + imageStream.Read(header, 0, header.Length); + imageStream.Position = originalPosition; + + if (header[0] == 0x89 && header[1] == 0x50 && header[2] == 0x4E && header[3] == 0x47) + { + return PngFormat.Instance; + } + if (header[0] == 0xFF && header[1] == 0xD8) + { + return JpegFormat.Instance; + } + if (header[0] == 0x47 && header[1] == 0x49 && header[2] == 0x46) + { + return GifFormat.Instance; + } + if (header[0] == 0x42 && header[1] == 0x4D) + { + return BmpFormat.Instance; + } + return null; + } + } + } +} \ No newline at end of file diff --git a/src/Magicodes.ExporterAndImporter.Core/Magicodes.IE.Core.csproj b/src/Magicodes.ExporterAndImporter.Core/Magicodes.IE.Core.csproj index e8627c2d..ec722c75 100644 --- a/src/Magicodes.ExporterAndImporter.Core/Magicodes.IE.Core.csproj +++ b/src/Magicodes.ExporterAndImporter.Core/Magicodes.IE.Core.csproj @@ -27,19 +27,19 @@ - + - + - + diff --git a/src/Magicodes.ExporterAndImporter.Excel/Images/ImageExtensions.cs b/src/Magicodes.ExporterAndImporter.Excel/Images/ImageExtensions.cs index 3d9c7c40..bfe05b12 100644 --- a/src/Magicodes.ExporterAndImporter.Excel/Images/ImageExtensions.cs +++ b/src/Magicodes.ExporterAndImporter.Excel/Images/ImageExtensions.cs @@ -4,10 +4,17 @@ using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Metadata; +using SkiaSharp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.Metadata.Profiles.Exif; +using Magicodes.IE.EPPlus; +using SixLabors.ImageSharp.Memory; +using System.Text.RegularExpressions; namespace Magicodes.IE.Excel.Images { - internal static class ImageExtensions + internal static partial class ImageExtensions { public static string SaveTo(this Image image, string path) { @@ -39,34 +46,52 @@ public static Image GetImageByUrl(this string url, out IImageFormat format) using (var wc = new WebClient()) { wc.Proxy = null; - var image = Image.Load(wc.OpenRead(url), out format); - if (image.Metadata.HorizontalResolution == 0 && image.Metadata.VerticalResolution == 0) + using (Stream webStream = wc.OpenRead(url)) { - image.Metadata.HorizontalResolution = ImageMetadata.DefaultHorizontalResolution; - image.Metadata.VerticalResolution = ImageMetadata.DefaultVerticalResolution; + using (MemoryStream memoryStream = new MemoryStream()) + { + webStream.CopyTo(memoryStream); + memoryStream.Position = 0; + + var image = Image.Load(memoryStream); + format = image.GetImageFormat(memoryStream); + + if (image.Metadata.HorizontalResolution == 0 && image.Metadata.VerticalResolution == 0) + { + image.Metadata.HorizontalResolution = ImageMetadata.DefaultHorizontalResolution; + image.Metadata.VerticalResolution = ImageMetadata.DefaultVerticalResolution; + } + return image; + } } - return image; } } /// - /// base64转Bitmap + /// Converts a base64 string to an Image /// - /// - /// - /// + /// The base64 string representing the image + /// The image format + /// An Image object representing the base64 string public static Image Base64StringToImage(this string base64String, out IImageFormat format) { - var bytes = Convert.FromBase64String(FixBase64ForImage(base64String)); - return Image.Load(bytes, out format); + byte[] bytes = Convert.FromBase64String(CleanupBase64String(base64String)); + using (MemoryStream stream = new MemoryStream(bytes)) + { + Image image = Image.Load(stream); + format = image.GetImageFormat(stream); + return image; + } } - private static string FixBase64ForImage(string image) + /// + /// Cleans up the base64 string by removing unnecessary characters + /// + /// The base64 string to clean up + /// A cleaned-up base64 string + private static string CleanupBase64String(string base64String) { - var sbText = new System.Text.StringBuilder(image, image.Length); - sbText.Replace("\r\n", string.Empty); - sbText.Replace(" ", string.Empty); - return sbText.ToString(); + return Regex.Replace(base64String, @"\s+", string.Empty); } } } diff --git a/src/Magicodes.ExporterAndImporter.Excel/Utility/ImportHelper.cs b/src/Magicodes.ExporterAndImporter.Excel/Utility/ImportHelper.cs index e57017ec..7a7aebb8 100644 --- a/src/Magicodes.ExporterAndImporter.Excel/Utility/ImportHelper.cs +++ b/src/Magicodes.ExporterAndImporter.Excel/Utility/ImportHelper.cs @@ -778,7 +778,8 @@ protected virtual void ParseTemplate(ExcelPackage excelPackage) /// 解析头部 /// /// - /// 导入实体没有定义ImporterHeader属性 + /// 导入实体没有定义ImporterHeader属性 + /// protected virtual bool ParseHeader() { ImporterHeaderInfos = new List(); diff --git a/src/Magicodes.ExporterAndImporter.Excel/Utility/TemplateExport/TemplateExportHelper.cs b/src/Magicodes.ExporterAndImporter.Excel/Utility/TemplateExport/TemplateExportHelper.cs index d2fc5c67..6d9b0ff2 100644 --- a/src/Magicodes.ExporterAndImporter.Excel/Utility/TemplateExport/TemplateExportHelper.cs +++ b/src/Magicodes.ExporterAndImporter.Excel/Utility/TemplateExport/TemplateExportHelper.cs @@ -26,6 +26,9 @@ using Magicodes.IE.Excel.Images; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats; +using SkiaSharp; +using Magicodes.IE.EPPlus; +using System.Reflection; namespace Magicodes.ExporterAndImporter.Excel.Utility.TemplateExport { @@ -696,7 +699,13 @@ private bool RenderCellPipeline(Interpreter target, ExcelWorksheet sheet, ref st } else if (File.Exists(imageUrl)) { - image = Image.Load(imageUrl, out format); + using (Stream imageStream = File.OpenRead(imageUrl)) + { + image = Image.Load(imageStream); + format = image.GetImageFormat(imageStream); + } + + // image = Image.Load(imageUrl, out format); } if (image == null) @@ -719,7 +728,7 @@ private bool RenderCellPipeline(Interpreter target, ExcelWorksheet sheet, ref st excelImage.SetSize(width, height); } } - catch (Exception) + catch (Exception ex) { cell.Value = alt; }