diff --git a/src/ImageSharp/Image.FromBytes.cs b/src/ImageSharp/Image.FromBytes.cs
index 0850e2213f..f1196ac977 100644
--- a/src/ImageSharp/Image.FromBytes.cs
+++ b/src/ImageSharp/Image.FromBytes.cs
@@ -37,6 +37,46 @@ namespace SixLabors.ImageSharp
}
}
+ ///
+ /// Reads the raw image information from the specified stream without fully decoding it.
+ ///
+ /// The byte array containing encoded image data to read the header from.
+ /// Thrown if the stream is not readable.
+ ///
+ /// The or null if suitable info detector not found.
+ ///
+ public static IImageInfo Identify(byte[] data) => Identify(data, out IImageFormat _);
+
+ ///
+ /// Reads the raw image information from the specified stream without fully decoding it.
+ ///
+ /// The byte array containing encoded image data to read the header from.
+ /// The format type of the decoded image.
+ /// Thrown if the stream is not readable.
+ ///
+ /// The or null if suitable info detector not found.
+ ///
+ public static IImageInfo Identify(byte[] data, out IImageFormat format) => Identify(Configuration.Default, data, out format);
+
+ ///
+ /// Reads the raw image information from the specified stream without fully decoding it.
+ ///
+ /// The configuration.
+ /// The byte array containing encoded image data to read the header from.
+ /// The format type of the decoded image.
+ /// Thrown if the stream is not readable.
+ ///
+ /// The or null if suitable info detector is not found.
+ ///
+ public static IImageInfo Identify(Configuration config, byte[] data, out IImageFormat format)
+ {
+ config ??= Configuration.Default;
+ using (var stream = new MemoryStream(data))
+ {
+ return Identify(config, stream, out format);
+ }
+ }
+
///
/// Load a new instance of from the given encoded byte array.
///
diff --git a/src/ImageSharp/Image.FromFile.cs b/src/ImageSharp/Image.FromFile.cs
index 45ea378cfd..bb26e4142c 100644
--- a/src/ImageSharp/Image.FromFile.cs
+++ b/src/ImageSharp/Image.FromFile.cs
@@ -31,13 +31,53 @@ namespace SixLabors.ImageSharp
/// The mime type or null if none found.
public static IImageFormat DetectFormat(Configuration config, string filePath)
{
- config = config ?? Configuration.Default;
+ config ??= Configuration.Default;
using (Stream file = config.FileSystem.OpenRead(filePath))
{
return DetectFormat(config, file);
}
}
+ ///
+ /// Reads the raw image information from the specified stream without fully decoding it.
+ ///
+ /// The image file to open and to read the header from.
+ /// Thrown if the stream is not readable.
+ ///
+ /// The or null if suitable info detector not found.
+ ///
+ public static IImageInfo Identify(string filePath) => Identify(filePath, out IImageFormat _);
+
+ ///
+ /// Reads the raw image information from the specified stream without fully decoding it.
+ ///
+ /// The image file to open and to read the header from.
+ /// The format type of the decoded image.
+ /// Thrown if the stream is not readable.
+ ///
+ /// The or null if suitable info detector not found.
+ ///
+ public static IImageInfo Identify(string filePath, out IImageFormat format) => Identify(Configuration.Default, filePath, out format);
+
+ ///
+ /// Reads the raw image information from the specified stream without fully decoding it.
+ ///
+ /// The configuration.
+ /// The image file to open and to read the header from.
+ /// The format type of the decoded image.
+ /// Thrown if the stream is not readable.
+ ///
+ /// The or null if suitable info detector is not found.
+ ///
+ public static IImageInfo Identify(Configuration config, string filePath, out IImageFormat format)
+ {
+ config ??= Configuration.Default;
+ using (Stream file = config.FileSystem.OpenRead(filePath))
+ {
+ return Identify(config, file, out format);
+ }
+ }
+
///
/// Create a new instance of the class from the given file.
///
diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs
index d756ff7ac1..95a71903a8 100644
--- a/src/ImageSharp/Image.FromStream.cs
+++ b/src/ImageSharp/Image.FromStream.cs
@@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp
=> WithSeekableStream(config, stream, s => InternalDetectFormat(s, config));
///
- /// By reading the header on the provided stream this reads the raw image information.
+ /// Reads the raw image information from the specified stream without fully decoding it.
///
/// The image stream to read the header from.
/// Thrown if the stream is not readable.
@@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp
public static IImageInfo Identify(Stream stream) => Identify(stream, out IImageFormat _);
///
- /// By reading the header on the provided stream this reads the raw image information.
+ /// Reads the raw image information from the specified stream without fully decoding it.
///
/// The image stream to read the header from.
/// The format type of the decoded image.
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs
new file mode 100644
index 0000000000..2be9504079
--- /dev/null
+++ b/tests/ImageSharp.Tests/Image/ImageTests.Identify.cs
@@ -0,0 +1,99 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.IO;
+using SixLabors.ImageSharp.Formats;
+
+using Xunit;
+
+// ReSharper disable InconsistentNaming
+namespace SixLabors.ImageSharp.Tests
+{
+ public partial class ImageTests
+ {
+ ///
+ /// Tests the class.
+ ///
+ public class Identify : ImageLoadTestBase
+ {
+ private static readonly string ActualImagePath = TestFile.GetInputFileFullPath(TestImages.Bmp.F);
+
+ private byte[] ActualImageBytes => TestFile.Create(TestImages.Bmp.F).Bytes;
+
+ private byte[] ByteArray => this.DataStream.ToArray();
+
+ private IImageInfo LocalImageInfo => this.localImageInfoMock.Object;
+
+ private IImageFormat LocalImageFormat => this.localImageFormatMock.Object;
+
+ private static readonly IImageFormat ExpectedGlobalFormat =
+ Configuration.Default.ImageFormatsManager.FindFormatByFileExtension("bmp");
+
+ [Fact]
+ public void FromBytes_GlobalConfiguration()
+ {
+ IImageInfo info = Image.Identify(this.ActualImageBytes, out IImageFormat type);
+
+ Assert.NotNull(info);
+ Assert.Equal(ExpectedGlobalFormat, type);
+ }
+
+ [Fact]
+ public void FromBytes_CustomConfiguration()
+ {
+ IImageInfo info = Image.Identify(this.LocalConfiguration, this.ByteArray, out IImageFormat type);
+
+ Assert.Equal(this.LocalImageInfo, info);
+ Assert.Equal(this.LocalImageFormat, type);
+ }
+
+ [Fact]
+ public void FromFileSystemPath_GlobalConfiguration()
+ {
+ IImageInfo info = Image.Identify(ActualImagePath, out IImageFormat type);
+
+ Assert.NotNull(info);
+ Assert.Equal(ExpectedGlobalFormat, type);
+ }
+
+ [Fact]
+ public void FromFileSystemPath_CustomConfiguration()
+ {
+ IImageInfo info = Image.Identify(this.LocalConfiguration, this.MockFilePath, out IImageFormat type);
+
+ Assert.Equal(this.LocalImageInfo, info);
+ Assert.Equal(this.LocalImageFormat, type);
+ }
+
+ [Fact]
+ public void FromStream_GlobalConfiguration()
+ {
+ using (var stream = new MemoryStream(this.ActualImageBytes))
+ {
+ IImageInfo info = Image.Identify(stream, out IImageFormat type);
+
+ Assert.NotNull(info);
+ Assert.Equal(ExpectedGlobalFormat, type);
+ }
+ }
+
+ [Fact]
+ public void FromStream_CustomConfiguration()
+ {
+ IImageInfo info = Image.Identify(this.LocalConfiguration, this.DataStream, out IImageFormat type);
+
+ Assert.Equal(this.LocalImageInfo, info);
+ Assert.Equal(this.LocalImageFormat, type);
+ }
+
+ [Fact]
+ public void WhenNoMatchingFormatFound_ReturnsNull()
+ {
+ IImageInfo info = Image.Identify(new Configuration(), this.DataStream, out IImageFormat type);
+
+ Assert.Null(info);
+ Assert.Null(type);
+ }
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs
index dff83df26d..d010f60236 100644
--- a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs
+++ b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs
@@ -26,6 +26,8 @@ namespace SixLabors.ImageSharp.Tests
protected Mock localImageFormatMock;
+ protected Mock localImageInfoMock;
+
protected readonly string MockFilePath = Guid.NewGuid().ToString();
internal readonly Mock LocalFileSystemMock = new Mock();
@@ -53,9 +55,12 @@ namespace SixLabors.ImageSharp.Tests
this.localStreamReturnImageRgba32 = new Image(1, 1);
this.localStreamReturnImageAgnostic = new Image(1, 1);
+ this.localImageInfoMock = new Mock();
this.localImageFormatMock = new Mock();
- this.localDecoder = new Mock();
+ var detector = new Mock();
+ detector.Setup(x => x.Identify(It.IsAny(), It.IsAny())).Returns(this.localImageInfoMock.Object);
+ this.localDecoder = detector.As();
this.localMimeTypeDetector = new MockImageFormatDetector(this.localImageFormatMock.Object);
this.localDecoder.Setup(x => x.Decode(It.IsAny(), It.IsAny()))
@@ -80,9 +85,7 @@ namespace SixLabors.ImageSharp.Tests
})
.Returns(this.localStreamReturnImageAgnostic);
- this.LocalConfiguration = new Configuration
- {
- };
+ this.LocalConfiguration = new Configuration();
this.LocalConfiguration.ImageFormatsManager.AddImageFormatDetector(this.localMimeTypeDetector);
this.LocalConfiguration.ImageFormatsManager.SetDecoder(this.localImageFormatMock.Object, this.localDecoder.Object);