diff --git a/ClosedXML/ClosedXML.csproj b/ClosedXML/ClosedXML.csproj
index 26cb10b..d935052 100644
--- a/ClosedXML/ClosedXML.csproj
+++ b/ClosedXML/ClosedXML.csproj
@@ -25,10 +25,6 @@
$(DefineConstants);_NETFRAMEWORK_;_NET461_
-
-
-
-
@@ -44,4 +40,8 @@
+
+
+
+
diff --git a/ClosedXML/Excel/Drawings/PictureEnums.cs b/ClosedXML/Excel/Drawings/PictureEnums.cs
index 3d76e73..f00f85b 100644
--- a/ClosedXML/Excel/Drawings/PictureEnums.cs
+++ b/ClosedXML/Excel/Drawings/PictureEnums.cs
@@ -14,9 +14,9 @@
Tiff = 3,
Icon = 4,
Pcx = 5,
- Jpeg = 6,
- Emf = 7,
- Wmf = 8
+ Jpeg = 6
+ //Emf = 7,
+ //Wmf = 8
}
public enum XLPicturePlacement
diff --git a/ClosedXML/Excel/Drawings/XLPicture.cs b/ClosedXML/Excel/Drawings/XLPicture.cs
index 4427664..7364606 100644
--- a/ClosedXML/Excel/Drawings/XLPicture.cs
+++ b/ClosedXML/Excel/Drawings/XLPicture.cs
@@ -1,15 +1,18 @@
+using MetadataExtractor;
+using MetadataExtractor.Formats.Bmp;
+using MetadataExtractor.Formats.Gif;
+using MetadataExtractor.Formats.Ico;
+using MetadataExtractor.Formats.Jpeg;
+using MetadataExtractor.Formats.Pcx;
+using MetadataExtractor.Formats.Png;
+using MetadataExtractor.Formats.Tiff;
+using MetadataExtractor.Util;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
-
-#if _NETFRAMEWORK_
-using System.Drawing.Imaging;
-#endif
-
using System.IO;
using System.Linq;
-using System.Reflection;
namespace ClosedXML.Excel.Drawings
{
@@ -17,26 +20,23 @@
internal class XLPicture : IXLPicture
{
private const String InvalidNameChars = @":\/?*[]";
+
+ private static IDictionary FormatMap = new Dictionary()
+ {
+ [FileType.Bmp] = XLPictureFormat.Bmp,
+ [FileType.Gif] = XLPictureFormat.Gif,
+ [FileType.Png] = XLPictureFormat.Png,
+ [FileType.Tiff] = XLPictureFormat.Tiff,
+ [FileType.Ico] = XLPictureFormat.Icon,
+ [FileType.Pcx] = XLPictureFormat.Pcx,
+ [FileType.Jpeg] = XLPictureFormat.Jpeg
+ };
+
private readonly IXLWorksheet _worksheet;
private Int32 height;
private String name = string.Empty;
private Int32 width;
-#if _NETFRAMEWORK_
- private static IDictionary FormatMap;
- static XLPicture()
- {
- var properties = typeof(ImageFormat).GetProperties(BindingFlags.Static | BindingFlags.Public);
- FormatMap = Enum.GetValues(typeof(XLPictureFormat))
- .Cast()
- .Where(pf => properties.Any(pi => pi.Name.Equals(pf.ToString(), StringComparison.OrdinalIgnoreCase)))
- .ToDictionary(
- pf => pf,
- pf => properties.Single(pi => pi.Name.Equals(pf.ToString(), StringComparison.OrdinalIgnoreCase)).GetValue(null, null) as ImageFormat
- );
- }
-#endif
-
internal XLPicture(IXLWorksheet worksheet, Stream stream)
: this(worksheet)
{
@@ -44,21 +44,14 @@
this.ImageStream = new MemoryStream();
{
- stream.Position = 0;
+ stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(ImageStream);
ImageStream.Seek(0, SeekOrigin.Begin);
-#if _NETFRAMEWORK_
- using (var bitmap = new Bitmap(ImageStream))
- {
- if (FormatMap.Values.Select(f => f.Guid).Contains(bitmap.RawFormat.Guid))
- this.Format = FormatMap.Single(f => f.Value.Guid.Equals(bitmap.RawFormat.Guid)).Key;
+ DeduceImageFormat(ImageStream);
+ DeduceDimensions(ImageStream);
- DeduceDimensionsFromBitmap(bitmap);
- }
ImageStream.Seek(0, SeekOrigin.Begin);
-#endif
-
}
}
@@ -70,23 +63,10 @@
this.ImageStream = new MemoryStream();
{
- stream.Position = 0;
+ stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(ImageStream);
- ImageStream.Seek(0, SeekOrigin.Begin);
-
-#if _NETFRAMEWORK_
- using (var bitmap = new Bitmap(ImageStream))
- {
- if (FormatMap.ContainsKey(this.Format))
- {
- if (FormatMap[this.Format].Guid != bitmap.RawFormat.Guid)
- throw new ArgumentException("The picture format in the stream and the parameter don't match");
- }
-
- DeduceDimensionsFromBitmap(bitmap);
- }
- ImageStream.Seek(0, SeekOrigin.Begin);
-#endif
+ DeduceImageFormat(ImageStream, format);
+ DeduceDimensions(ImageStream);
}
}
@@ -98,13 +78,8 @@
this.ImageStream = new MemoryStream();
bitmap.Save(ImageStream, bitmap.RawFormat);
ImageStream.Seek(0, SeekOrigin.Begin);
- DeduceDimensionsFromBitmap(bitmap);
-
- var formats = FormatMap.Where(f => f.Value.Guid.Equals(bitmap.RawFormat.Guid));
- if (!formats.Any() || formats.Count() > 1)
- throw new ArgumentException("Unsupported or unknown image format in bitmap");
-
- this.Format = formats.Single().Key;
+ DeduceImageFormat(ImageStream);
+ DeduceDimensions(ImageStream);
}
#endif
@@ -336,37 +311,76 @@
return this;
}
-#if _NETFRAMEWORK_
- private static ImageFormat FromMimeType(string mimeType)
+ private void DeduceDimensions(Stream stream)
{
- var guid = ImageCodecInfo.GetImageDecoders().FirstOrDefault(c => c.MimeType.Equals(mimeType, StringComparison.OrdinalIgnoreCase))?.FormatID;
- if (!guid.HasValue) return null;
- var property = typeof(System.Drawing.Imaging.ImageFormat).GetProperties(BindingFlags.Public | BindingFlags.Static)
- .FirstOrDefault(pi => (pi.GetValue(null, null) as ImageFormat).Guid.Equals(guid.Value));
-
- if (property == null) return null;
- return (property.GetValue(null, null) as ImageFormat);
- }
-
- private static string GetMimeType(Image i)
- {
- var imgguid = i.RawFormat.Guid;
- foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageDecoders())
+ stream.Seek(0, SeekOrigin.Begin);
+ MetadataExtractor.Directory d;
+ switch (this.Format)
{
- if (codec.FormatID == imgguid)
- return codec.MimeType;
+ case XLPictureFormat.Bmp:
+ d = BmpMetadataReader.ReadMetadata(stream);
+ this.width = d.GetInt32(BmpHeaderDirectory.TagImageWidth);
+ this.height = d.GetInt32(BmpHeaderDirectory.TagImageHeight);
+ break;
+
+ case XLPictureFormat.Gif:
+ d = GifMetadataReader.ReadMetadata(stream).OfType().First();
+ this.width = d.GetInt32(GifHeaderDirectory.TagImageWidth);
+ this.height = d.GetInt32(GifHeaderDirectory.TagImageHeight);
+ break;
+
+ case XLPictureFormat.Png:
+ d = PngMetadataReader.ReadMetadata(stream).OfType().First();
+ this.width = d.GetInt32(PngDirectory.TagImageWidth);
+ this.height = d.GetInt32(PngDirectory.TagImageHeight);
+ break;
+
+ case XLPictureFormat.Tiff:
+ d = TiffMetadataReader.ReadMetadata(stream).First();
+ throw new NotImplementedException();
+ //this.width = d.GetInt32(tiff.TagImageWidth);
+ //this.height = d.GetInt32(PngDirectory.TagImageHeight);
+ break;
+
+ case XLPictureFormat.Icon:
+ d = IcoMetadataReader.ReadMetadata(stream).OfType().First();
+ this.width = d.GetInt32(IcoDirectory.TagImageWidth);
+ this.height = d.GetInt32(IcoDirectory.TagImageHeight);
+ break;
+
+ case XLPictureFormat.Pcx:
+ d = PcxMetadataReader.ReadMetadata(stream);
+ this.width = d.GetInt32(PcxDirectory.TagXMax);
+ this.height = d.GetInt32(PcxDirectory.TagYMax);
+ break;
+
+ case XLPictureFormat.Jpeg:
+ d = JpegMetadataReader.ReadMetadata(stream).OfType().First();
+ this.width = d.GetInt32(JpegDirectory.TagImageWidth);
+ this.height = d.GetInt32(JpegDirectory.TagImageHeight);
+ break;
}
- return "image/unknown";
+ this.OriginalWidth = this.width;
+ this.OriginalHeight = this.height;
}
- private void DeduceDimensionsFromBitmap(Bitmap bitmap)
+ private void DeduceImageFormat(Stream stream, XLPictureFormat format)
{
- this.OriginalWidth = bitmap.Width;
- this.OriginalHeight = bitmap.Height;
-
- this.width = bitmap.Width;
- this.height = bitmap.Height;
+ DeduceImageFormat(stream);
+ if (this.Format != format)
+ throw new ArgumentException(nameof(format));
}
-#endif
+
+ private void DeduceImageFormat(Stream stream)
+ {
+ stream.Seek(0, SeekOrigin.Begin);
+ var fileType = FileTypeDetector.DetectFileType(stream);
+ if (fileType == FileType.Unknown)
+ throw new NotImplementedException();
+ else if (FormatMap.ContainsKey(fileType))
+ this.Format = FormatMap[fileType];
+ else
+ throw new NotImplementedException();
+ }
}
}
diff --git a/ClosedXML/Excel/Drawings/XLPictures.cs b/ClosedXML/Excel/Drawings/XLPictures.cs
index aa62fee..aa72c5e 100644
--- a/ClosedXML/Excel/Drawings/XLPictures.cs
+++ b/ClosedXML/Excel/Drawings/XLPictures.cs
@@ -73,18 +73,13 @@
public IXLPicture Add(string imageFile)
{
-#if _NETFRAMEWORK_
-
- using (var bitmap = Image.FromFile(imageFile) as Bitmap)
+ using (var fs = File.Open(imageFile, FileMode.Open))
{
- var picture = new XLPicture(_worksheet, bitmap);
+ var picture = new XLPicture(_worksheet, fs);
_pictures.Add(picture);
picture.Name = GetNextPictureName();
return picture;
}
-#else
- throw new NotImplementedException("System.Drawing.Image is not supported in .NET Standard");
-#endif
}
public IXLPicture Add(string imageFile, string name)
diff --git a/ClosedXML/Excel/XLWorkbook_Load.cs b/ClosedXML/Excel/XLWorkbook_Load.cs
index d8ebf53..035f52c 100644
--- a/ClosedXML/Excel/XLWorkbook_Load.cs
+++ b/ClosedXML/Excel/XLWorkbook_Load.cs
@@ -632,10 +632,12 @@
var imagePart = drawingsPart.GetPartById(imgId);
using (var stream = imagePart.GetStream())
+ using (var ms = new MemoryStream())
{
+ stream.CopyTo(ms);
var vsdp = GetPropertiesFromAnchor(anchor);
- var picture = ws.AddPicture(stream, vsdp.Name) as XLPicture;
+ var picture = ws.AddPicture(ms, vsdp.Name) as XLPicture;
picture.RelId = imgId;
Xdr.ShapeProperties spPr = anchor.Descendants().First();
@@ -2398,4 +2400,4 @@
return false;
}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Tests/Examples/ImageHandlingTests.cs b/ClosedXML_Tests/Examples/ImageHandlingTests.cs
index 02a87dd..cbbbd94 100644
--- a/ClosedXML_Tests/Examples/ImageHandlingTests.cs
+++ b/ClosedXML_Tests/Examples/ImageHandlingTests.cs
@@ -1,4 +1,3 @@
-#if _NETFRAMEWORK_
using ClosedXML_Examples;
using NUnit.Framework;
@@ -20,4 +19,3 @@
}
}
}
-#endif
\ No newline at end of file
diff --git a/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs b/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs
index 6f544fa..6539785 100644
--- a/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs
+++ b/ClosedXML_Tests/Excel/ImageHandling/PictureTests.cs
@@ -7,12 +7,12 @@
using System.Linq;
using System.Reflection;
-#if _NETFRAMEWORK_
namespace ClosedXML_Tests
{
[TestFixture]
public class PictureTests
{
+#if _NETFRAMEWORK_
[Test]
public void CanAddPictureFromBitmap()
{
@@ -34,6 +34,28 @@
}
}
}
+#endif
+
+ [Test]
+ public void CanAddPictureFromStream()
+ {
+ using (var wb = new XLWorkbook())
+ {
+ var ws = wb.AddWorksheet("Sheet1");
+
+ using (var resourceStream = Assembly.GetAssembly(typeof(ClosedXML_Examples.BasicTable)).GetManifestResourceStream("ClosedXML_Examples.Resources.SampleImage.jpg"))
+ {
+ var picture = ws.AddPicture(resourceStream, "MyPicture")
+ .WithPlacement(XLPicturePlacement.FreeFloating)
+ .MoveTo(50, 50)
+ .WithSize(200, 200);
+
+ Assert.AreEqual(XLPictureFormat.Jpeg, picture.Format);
+ Assert.AreEqual(200, picture.Width);
+ Assert.AreEqual(200, picture.Height);
+ }
+ }
+ }
[Test]
public void CanAddPictureFromFile()
@@ -78,9 +100,8 @@
var ws = wb.AddWorksheet("Sheet1");
using (var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ClosedXML_Tests.Resource.Images.ImageHandling.png"))
- using (var bitmap = Bitmap.FromStream(resourceStream) as Bitmap)
{
- var pic = ws.AddPicture(bitmap, "MyPicture")
+ var pic = ws.AddPicture(resourceStream, "MyPicture")
.WithPlacement(XLPicturePlacement.FreeFloating)
.MoveTo(50, 50);
@@ -234,4 +255,3 @@
}
}
}
-#endif
\ No newline at end of file