Skip to content

Commit 5dfda94

Browse files
committed
Added WriteAsync to MagickImageCollection.
1 parent 7949001 commit 5dfda94

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed

src/Magick.NET.Core/IMagickImageCollection.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,5 +394,35 @@ public interface IMagickImageCollection : IDisposable
394394
/// <param name="format">The format to use.</param>
395395
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
396396
void Write(string fileName, MagickFormat format);
397+
398+
#if NETSTANDARD
399+
/// <summary>
400+
/// Writes the imagse to the specified stream. If the output image's file format does not
401+
/// allow multi-image files multiple files will be written.
402+
/// </summary>
403+
/// <param name="stream">The stream to write the images to.</param>
404+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
405+
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
406+
Task WriteAsync(Stream stream);
407+
408+
/// <summary>
409+
/// Writes the imagse to the specified stream. If the output image's file format does not
410+
/// allow multi-image files multiple files will be written.
411+
/// </summary>
412+
/// <param name="stream">The stream to write the images to.</param>
413+
/// <param name="defines">The defines to set.</param>
414+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
415+
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
416+
Task WriteAsync(Stream stream, IWriteDefines defines);
417+
418+
/// <summary>
419+
/// Writes the image to the specified stream.
420+
/// </summary>
421+
/// <param name="stream">The stream to write the image data to.</param>
422+
/// <param name="format">The format to use.</param>
423+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
424+
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
425+
Task WriteAsync(Stream stream, MagickFormat format);
426+
#endif
397427
}
398428
}

src/Magick.NET/MagickImageCollection.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,66 @@ public void Write(string fileName, MagickFormat format)
15511551
Write(fileName);
15521552
}
15531553

1554+
#if NETSTANDARD
1555+
/// <summary>
1556+
/// Writes the imagse to the specified stream. If the output image's file format does not
1557+
/// allow multi-image files multiple files will be written.
1558+
/// </summary>
1559+
/// <param name="stream">The stream to write the images to.</param>
1560+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
1561+
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
1562+
public async Task WriteAsync(Stream stream)
1563+
{
1564+
Throw.IfNull(nameof(stream), stream);
1565+
1566+
if (_images.Count == 0)
1567+
return;
1568+
1569+
var settings = _images[0].GetSettings().Clone();
1570+
settings.FileName = null;
1571+
1572+
try
1573+
{
1574+
AttachImages();
1575+
1576+
var bytes = ToByteArray();
1577+
await stream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
1578+
}
1579+
finally
1580+
{
1581+
DetachImages();
1582+
}
1583+
}
1584+
1585+
/// <summary>
1586+
/// Writes the imagse to the specified stream. If the output image's file format does not
1587+
/// allow multi-image files multiple files will be written.
1588+
/// </summary>
1589+
/// <param name="stream">The stream to write the images to.</param>
1590+
/// <param name="defines">The defines to set.</param>
1591+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
1592+
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
1593+
public Task WriteAsync(Stream stream, IWriteDefines defines)
1594+
{
1595+
SetDefines(defines);
1596+
SetFormat(defines.Format);
1597+
return WriteAsync(stream);
1598+
}
1599+
1600+
/// <summary>
1601+
/// Writes the image to the specified stream.
1602+
/// </summary>
1603+
/// <param name="stream">The stream to write the image data to.</param>
1604+
/// <param name="format">The format to use.</param>
1605+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
1606+
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
1607+
public Task WriteAsync(Stream stream, MagickFormat format)
1608+
{
1609+
SetFormat(format);
1610+
return WriteAsync(stream);
1611+
}
1612+
#endif
1613+
15541614
private static MagickSettings CreateSettings(IMagickReadSettings<QuantumType> readSettings)
15551615
{
15561616
if (readSettings == null)
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright 2013-2020 Dirk Lemstra <https://github.com/dlemstra/Magick.NET/>
2+
//
3+
// Licensed under the ImageMagick License (the "License"); you may not use this file except in
4+
// compliance with the License. You may obtain a copy of the License at
5+
//
6+
// https://www.imagemagick.org/script/license.php
7+
//
8+
// Unless required by applicable law or agreed to in writing, software distributed under the
9+
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
10+
// either express or implied. See the License for the specific language governing permissions
11+
// and limitations under the License.
12+
13+
#if NETCOREAPP
14+
using System;
15+
using System.IO;
16+
using System.Threading.Tasks;
17+
using ImageMagick;
18+
using Xunit;
19+
20+
namespace Magick.NET.Tests
21+
{
22+
public partial class MagickImageCollectionTests
23+
{
24+
public class TheWriteAsyncMethod
25+
{
26+
public class WithStream
27+
{
28+
[Fact]
29+
public async Task ShouldThrowExceptionWhenFileIsNull()
30+
{
31+
using (var images = new MagickImageCollection())
32+
{
33+
await Assert.ThrowsAsync<ArgumentNullException>("stream", () => images.WriteAsync(null));
34+
}
35+
}
36+
}
37+
38+
public class WithStreamAndFormat
39+
{
40+
[Fact]
41+
public async Task ShouldThrowExceptionWhenStreamIsNull()
42+
{
43+
using (var images = new MagickImageCollection())
44+
{
45+
await Assert.ThrowsAsync<ArgumentNullException>("stream", () => images.WriteAsync(null, MagickFormat.Bmp));
46+
}
47+
}
48+
49+
[Fact]
50+
public async Task ShouldUseTheSpecifiedFormat()
51+
{
52+
using (var input = new MagickImageCollection(Files.CirclePNG))
53+
{
54+
using (var memoryStream = new MemoryStream())
55+
{
56+
using (var stream = new NonSeekableStream(memoryStream))
57+
{
58+
await input.WriteAsync(stream, MagickFormat.Tiff);
59+
60+
memoryStream.Position = 0;
61+
using (var output = new MagickImageCollection(stream))
62+
{
63+
Assert.Single(output);
64+
Assert.Equal(MagickFormat.Tiff, output[0].Format);
65+
}
66+
}
67+
}
68+
}
69+
}
70+
71+
[Fact]
72+
public async Task ShouldThrowExceptionWhenFormatIsNotWritable()
73+
{
74+
using (var input = new MagickImageCollection(Files.CirclePNG))
75+
{
76+
using (var memoryStream = new MemoryStream())
77+
{
78+
await Assert.ThrowsAsync<MagickMissingDelegateErrorException>(() => input.WriteAsync(memoryStream, MagickFormat.Xc));
79+
}
80+
}
81+
}
82+
}
83+
}
84+
}
85+
}
86+
#endif

0 commit comments

Comments
 (0)