LEADTOOLS support loading and saving images using asynchronous operations with .NET async
and await
functionality. This support is included in the .NET Standard toolkit and is added through extensions methods in the .NET Framework toolkit using the Leadtools.Async.dll assembly.
The RasterCodecs class contains the following asynchronous methods for dealing with images:
All of these methods accepts as the first parameter an object of type ILeadStream that determine the input stream (in load or getting information) or output stream (in save) to use. The methods also return a .NET Task
object with result and can be used with the async
keyword.
ILeadStream is an interface that has the following implementation in LEADTOOLS:
Class | Description |
---|---|
LeadStream | ILeadStream support for any .NET System.IO.Stream |
LeadFileStream | ILeadStream support for a physical file disk. |
HttpClientLeadStream | ILeadStream support for a remote URL |
The main implementation is the LeadStream class that wraps a .NET System.IO.Stream
. LeadStream
also contains the Factory class member that can be used to quickly create ILeadStream
objects form various input or output sources.
LeadStream.Factory.FromStream: Wraps a .NET System.IO.Stream
. If the input/output image data is in a .NET stream, then simply create a new ILeadStream
using the following:
System.IO.Stream stream = ...
ILeadStream leadStream = LeadStream.Factory.FromStream(stream);
For example, the following code snippet will load an image from a .NET memory stream:
public static async Task Example()
{
// Load a file into a memory stream
string fileName = @"C:\LEADTOOLS23\Resources\Images\ocr1.tif";
using (Stream stream = new MemoryStream(File.ReadAllBytes(fileName)))
{
// Create an ILeadStream from the .NET stream
using (ILeadStream leadStream = LeadStream.Factory.FromStream(stream))
{
// Load an image asynchronously
using (var rasterCodecs = new RasterCodecs())
{
using (RasterImage image = await rasterCodecs.LoadAsync(leadStream))
{
// Use the image
Console.WriteLine($"Image loaded, size is {image.Width} by {image.Height} pixels");
}
}
}
}
}
The FromStream method accepts the autoDisposeStream boolean parameter that is false by default. This parameter determines the ownership of the underlying stream and will be set into the ILeadStream.DisposeStream property. For example, the above code can be modified as follows to transfer the ownership of the memory stream to ILeadStream
and thus will be disposed when the leadStream
object is disposed:
// Removing the using from here
Stream stream = new MemoryStream(File.ReadAllBytes(fileName));
// Create an ILeadStream from the .NET stream
// Pass true to transfer the ownership to ILeadStream:
using (ILeadStream leadStream = LeadStream.Factory.FromStream(stream, true))
{
// Should be true:
System.Diagnostics.Debug.Assert(leadStream.DisposeStream);
// Load an image asynchronously
using (var rasterCodecs = new RasterCodecs())
{
using (RasterImage image = await rasterCodecs.LoadAsync(leadStream))
{
// Use the image
Console.WriteLine($"Image loaded, size is {image.Width} by {image.Height} pixels");
}
}
// The next statement Disposes ILeadStream and since DisposeStream property is true, will also
// 'stream' will also be disposed
}
FromStream supports seekable and non-seekable streams. If the stream is non-seekable, it will internally use the RasterCodecs feed load mechanism to perform the action. Refer to RasterCodecs.StartFeedLoad for more information. Example using non-seekable stream (in this instance, a stream to a resource in a remote URL):
using (var httpClient = new HttpClient())
{
var url = "https://demo.leadtools.com/images/tiff/ocr1.tif";
using (var stream = await httpClient.GetStreamAsync(url))
{
// Create an ILeadStream from the .NET stream
using (ILeadStream leadStream = LeadStream.Factory.FromStream(stream))
{
// Load an image asynchronously
using (var rasterCodecs = new RasterCodecs())
{
using (RasterImage image = await rasterCodecs.LoadAsync(leadStream))
{
// Use the image
Console.WriteLine($"Image loaded, size is {image.Width} by {image.Height} pixels");
}
}
}
}
}
The HttpClientLeadStream implementation of ILeadStream is designed to perform exactly as the above and LeadStream.Factory contains the LeadStream.Factory.FromUri helper method for creating ILeadStream
objects from a .NET Uri
object. For example, the code above can be simplified as follows:
var url = "https://demo.leadtools.com/images/tiff/ocr1.tif";
// Create an ILeadStream from a URI
using (ILeadStream leadStream = await LeadStream.Factory.FromUri(new Uri(url)))
{
// Load an image asynchronously
using (var rasterCodecs = new RasterCodecs())
{
using (RasterImage image = await rasterCodecs.LoadAsync(leadStream))
{
// Use the image
Console.WriteLine($"Image loaded, size is {image.Width} by {image.Height} pixels");
}
}
}
HttpClientLeadStream automatically creates a .NET HttpClient
object and sets it in the static HttpClientLeadStream.HttpClient that can be used to customize the options used.
The LeadFileStream implementation of ILeadStream is designed to work with a physical file on disk. An object can be created with the desired access and share modes or by using the LeadStream.Factory.OpenFile and LeadStream.Factory.CreateFile helper methods as follows:
string inputFileName = @"C:\LEADTOOLS23\Resources\Images\ocr1.tif";
string outputFileName = @"C:\LEADTOOLS23\Resources\Images\ocr1-saved.png";
RasterImage image;
using (var rasterCodecs = new RasterCodecs())
{
// Create an ILeadStream from an input file
using (ILeadStream leadStream = LeadStream.Factory.OpenFile(inputFileName))
{
// Load the image asynchronously
image = await rasterCodecs.LoadAsync(leadStream);
}
// Create an ILeadStream for the output file
// Create an ILeadStream from an input file
using (ILeadStream leadStream = LeadStream.Factory.CreateFile(outputFileName))
{
// Save the image asynchronously
await rasterCodecs.SaveAsync(image, leadStream, RasterImageFormat.Png, 0);
}
}