Ping-ing a file to get dimensions whilst streaming it elsewhere #1713
-
Hi Magick.NET community. Thank you in advance for a great library and for helping out 👍 I have a .NET I'd also like to be able to leverage I have to assume that the I'm looking for perhaps a "decorator" approach where I can wrap the Any ideas would be much appreciated! Thank you! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
This feels like a premature optimization and there is no build in method to do this. You will need to create a stream that would read a byte buffer from disk give it to ImageMagick and then write that output buffer to your AWS stream in another thread. |
Beta Was this translation helpful? Give feedback.
-
Thank you @dlemstra. I ended up taking a approach similar to what you suggested. |
Beta Was this translation helpful? Give feedback.
-
For anyone interested in how I solved this, I made use of Here is some pseudo code: Stream inbound = ; // Stream from ASP.NET Core
long contentLength = ; // Value of incoming Content-Length header
var pipe = new Pipe();
// Decorator copies bytes from wrapped inbound stream to the PipeWriter as data is read.
using var multiplexer = new Multiplexer(wrapped: inbound, pipe.Writer);
// Another decorator conveys the length of the stream being ingested since S3 needs to know that.
using var outbound = new KnownLengthStream(wrapped: pipe.Reader.AsStream(), contentLength);
// Commence the S3 upload of the outbound stream.
var putObjectResponseTask = s3.PutObjectAsync(outbound); // Note that we are NOT awaiting here.
// In parallel with the upload, "ping" the image on the multiplexing stream.
// This causes Magick.NET to start to walk the stream, which fills the pipe and makes data available to S3.
using var image = new MagickImage();
image.Ping(multiplexer);
var width = image.Wiidth;
var height = image.Height;
if (multiplexer.Position < contentLength)
{
// Do a sanity check to ensure that we've walked the entire stream. If we haven't (if Magick.NET has been able to
// extract dimensions without walking the entire stream), then it's important to drain the rest of the incoming stream
// into the multiplexer so that all bytes get written to S3.
await multiplexer.DrainAsync(...).ConfigureAwait(false);
}
// Await the S3 upload finishing.
await putObjectResponseTask.ConfigureAwait(false); |
Beta Was this translation helpful? Give feedback.
This feels like a premature optimization and there is no build in method to do this. You will need to create a stream that would read a byte buffer from disk give it to ImageMagick and then write that output buffer to your AWS stream in another thread.