Skip to content

Commit 29b709d

Browse files
Add overloads. Fix #1144
1 parent 3042f83 commit 29b709d

File tree

5 files changed

+189
-7
lines changed

5 files changed

+189
-7
lines changed

src/ImageSharp/Image.FromBytes.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,46 @@ public static IImageFormat DetectFormat(Configuration config, byte[] data)
3737
}
3838
}
3939

40+
/// <summary>
41+
/// Reads the raw image information from the specified stream without fully decoding it.
42+
/// </summary>
43+
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
44+
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
45+
/// <returns>
46+
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
47+
/// </returns>
48+
public static IImageInfo Identify(byte[] data) => Identify(data, out IImageFormat _);
49+
50+
/// <summary>
51+
/// Reads the raw image information from the specified stream without fully decoding it.
52+
/// </summary>
53+
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
54+
/// <param name="format">The format type of the decoded image.</param>
55+
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
56+
/// <returns>
57+
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
58+
/// </returns>
59+
public static IImageInfo Identify(byte[] data, out IImageFormat format) => Identify(Configuration.Default, data, out format);
60+
61+
/// <summary>
62+
/// Reads the raw image information from the specified stream without fully decoding it.
63+
/// </summary>
64+
/// <param name="config">The configuration.</param>
65+
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
66+
/// <param name="format">The format type of the decoded image.</param>
67+
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
68+
/// <returns>
69+
/// The <see cref="IImageInfo"/> or null if suitable info detector is not found.
70+
/// </returns>
71+
public static IImageInfo Identify(Configuration config, byte[] data, out IImageFormat format)
72+
{
73+
config ??= Configuration.Default;
74+
using (var stream = new MemoryStream(data))
75+
{
76+
return Identify(config, stream, out format);
77+
}
78+
}
79+
4080
/// <summary>
4181
/// Load a new instance of <see cref="Image{Rgba32}"/> from the given encoded byte array.
4282
/// </summary>

src/ImageSharp/Image.FromFile.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,53 @@ public static IImageFormat DetectFormat(string filePath)
3131
/// <returns>The mime type or null if none found.</returns>
3232
public static IImageFormat DetectFormat(Configuration config, string filePath)
3333
{
34-
config = config ?? Configuration.Default;
34+
config ??= Configuration.Default;
3535
using (Stream file = config.FileSystem.OpenRead(filePath))
3636
{
3737
return DetectFormat(config, file);
3838
}
3939
}
4040

41+
/// <summary>
42+
/// Reads the raw image information from the specified stream without fully decoding it.
43+
/// </summary>
44+
/// <param name="filePath">The image file to open and to read the header from.</param>
45+
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
46+
/// <returns>
47+
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
48+
/// </returns>
49+
public static IImageInfo Identify(string filePath) => Identify(filePath, out IImageFormat _);
50+
51+
/// <summary>
52+
/// Reads the raw image information from the specified stream without fully decoding it.
53+
/// </summary>
54+
/// <param name="filePath">The image file to open and to read the header from.</param>
55+
/// <param name="format">The format type of the decoded image.</param>
56+
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
57+
/// <returns>
58+
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
59+
/// </returns>
60+
public static IImageInfo Identify(string filePath, out IImageFormat format) => Identify(Configuration.Default, filePath, out format);
61+
62+
/// <summary>
63+
/// Reads the raw image information from the specified stream without fully decoding it.
64+
/// </summary>
65+
/// <param name="config">The configuration.</param>
66+
/// <param name="filePath">The image file to open and to read the header from.</param>
67+
/// <param name="format">The format type of the decoded image.</param>
68+
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
69+
/// <returns>
70+
/// The <see cref="IImageInfo"/> or null if suitable info detector is not found.
71+
/// </returns>
72+
public static IImageInfo Identify(Configuration config, string filePath, out IImageFormat format)
73+
{
74+
config ??= Configuration.Default;
75+
using (Stream file = config.FileSystem.OpenRead(filePath))
76+
{
77+
return Identify(config, file, out format);
78+
}
79+
}
80+
4181
/// <summary>
4282
/// Create a new instance of the <see cref="Image"/> class from the given file.
4383
/// </summary>

src/ImageSharp/Image.FromStream.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public static IImageFormat DetectFormat(Configuration config, Stream stream)
3434
=> WithSeekableStream(config, stream, s => InternalDetectFormat(s, config));
3535

3636
/// <summary>
37-
/// By reading the header on the provided stream this reads the raw image information.
37+
/// Reads the raw image information from the specified stream without fully decoding it.
3838
/// </summary>
3939
/// <param name="stream">The image stream to read the header from.</param>
4040
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
@@ -44,7 +44,7 @@ public static IImageFormat DetectFormat(Configuration config, Stream stream)
4444
public static IImageInfo Identify(Stream stream) => Identify(stream, out IImageFormat _);
4545

4646
/// <summary>
47-
/// By reading the header on the provided stream this reads the raw image information.
47+
/// Reads the raw image information from the specified stream without fully decoding it.
4848
/// </summary>
4949
/// <param name="stream">The image stream to read the header from.</param>
5050
/// <param name="format">The format type of the decoded image.</param>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright (c) Six Labors and contributors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System.IO;
5+
using SixLabors.ImageSharp.Formats;
6+
7+
using Xunit;
8+
9+
// ReSharper disable InconsistentNaming
10+
namespace SixLabors.ImageSharp.Tests
11+
{
12+
public partial class ImageTests
13+
{
14+
/// <summary>
15+
/// Tests the <see cref="Image"/> class.
16+
/// </summary>
17+
public class Identify : ImageLoadTestBase
18+
{
19+
private static readonly string ActualImagePath = TestFile.GetInputFileFullPath(TestImages.Bmp.F);
20+
21+
private byte[] ActualImageBytes => TestFile.Create(TestImages.Bmp.F).Bytes;
22+
23+
private byte[] ByteArray => this.DataStream.ToArray();
24+
25+
private IImageInfo LocalImageInfo => this.localImageInfoMock.Object;
26+
27+
private IImageFormat LocalImageFormat => this.localImageFormatMock.Object;
28+
29+
private static readonly IImageFormat ExpectedGlobalFormat =
30+
Configuration.Default.ImageFormatsManager.FindFormatByFileExtension("bmp");
31+
32+
[Fact]
33+
public void FromBytes_GlobalConfiguration()
34+
{
35+
IImageInfo info = Image.Identify(this.ActualImageBytes, out IImageFormat type);
36+
37+
Assert.NotNull(info);
38+
Assert.Equal(ExpectedGlobalFormat, type);
39+
}
40+
41+
[Fact]
42+
public void FromBytes_CustomConfiguration()
43+
{
44+
IImageInfo info = Image.Identify(this.LocalConfiguration, this.ByteArray, out IImageFormat type);
45+
46+
Assert.Equal(this.LocalImageInfo, info);
47+
Assert.Equal(this.LocalImageFormat, type);
48+
}
49+
50+
[Fact]
51+
public void FromFileSystemPath_GlobalConfiguration()
52+
{
53+
IImageInfo info = Image.Identify(ActualImagePath, out IImageFormat type);
54+
55+
Assert.NotNull(info);
56+
Assert.Equal(ExpectedGlobalFormat, type);
57+
}
58+
59+
[Fact]
60+
public void FromFileSystemPath_CustomConfiguration()
61+
{
62+
IImageInfo info = Image.Identify(this.LocalConfiguration, this.MockFilePath, out IImageFormat type);
63+
64+
Assert.Equal(this.LocalImageInfo, info);
65+
Assert.Equal(this.LocalImageFormat, type);
66+
}
67+
68+
[Fact]
69+
public void FromStream_GlobalConfiguration()
70+
{
71+
using (var stream = new MemoryStream(this.ActualImageBytes))
72+
{
73+
IImageInfo info = Image.Identify(stream, out IImageFormat type);
74+
75+
Assert.NotNull(info);
76+
Assert.Equal(ExpectedGlobalFormat, type);
77+
}
78+
}
79+
80+
[Fact]
81+
public void FromStream_CustomConfiguration()
82+
{
83+
IImageInfo info = Image.Identify(this.LocalConfiguration, this.DataStream, out IImageFormat type);
84+
85+
Assert.Equal(this.LocalImageInfo, info);
86+
Assert.Equal(this.LocalImageFormat, type);
87+
}
88+
89+
[Fact]
90+
public void WhenNoMatchingFormatFound_ReturnsNull()
91+
{
92+
IImageInfo info = Image.Identify(new Configuration(), this.DataStream, out IImageFormat type);
93+
94+
Assert.Null(info);
95+
Assert.Null(type);
96+
}
97+
}
98+
}
99+
}

tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public abstract class ImageLoadTestBase : IDisposable
2626

2727
protected Mock<IImageFormat> localImageFormatMock;
2828

29+
protected Mock<IImageInfo> localImageInfoMock;
30+
2931
protected readonly string MockFilePath = Guid.NewGuid().ToString();
3032

3133
internal readonly Mock<IFileSystem> LocalFileSystemMock = new Mock<IFileSystem>();
@@ -53,9 +55,12 @@ protected ImageLoadTestBase()
5355
this.localStreamReturnImageRgba32 = new Image<Rgba32>(1, 1);
5456
this.localStreamReturnImageAgnostic = new Image<Bgra4444>(1, 1);
5557

58+
this.localImageInfoMock = new Mock<IImageInfo>();
5659
this.localImageFormatMock = new Mock<IImageFormat>();
5760

58-
this.localDecoder = new Mock<IImageDecoder>();
61+
var detector = new Mock<IImageInfoDetector>();
62+
detector.Setup(x => x.Identify(It.IsAny<Configuration>(), It.IsAny<Stream>())).Returns(this.localImageInfoMock.Object);
63+
this.localDecoder = detector.As<IImageDecoder>();
5964
this.localMimeTypeDetector = new MockImageFormatDetector(this.localImageFormatMock.Object);
6065

6166
this.localDecoder.Setup(x => x.Decode<Rgba32>(It.IsAny<Configuration>(), It.IsAny<Stream>()))
@@ -80,9 +85,7 @@ protected ImageLoadTestBase()
8085
})
8186
.Returns(this.localStreamReturnImageAgnostic);
8287

83-
this.LocalConfiguration = new Configuration
84-
{
85-
};
88+
this.LocalConfiguration = new Configuration();
8689
this.LocalConfiguration.ImageFormatsManager.AddImageFormatDetector(this.localMimeTypeDetector);
8790
this.LocalConfiguration.ImageFormatsManager.SetDecoder(this.localImageFormatMock.Object, this.localDecoder.Object);
8891

0 commit comments

Comments
 (0)