Skip to content

Commit a31a461

Browse files
Merge pull request #321 from SixLabors/js/issue-316
Use a single pipeline for images.
2 parents cc2fa1a + 2fece11 commit a31a461

File tree

3 files changed

+41
-50
lines changed

3 files changed

+41
-50
lines changed

src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs

+38-47
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,9 @@ private async Task Invoke(HttpContext httpContext, bool retry)
262262
}
263263

264264
await this.ProcessRequestAsync(
265-
httpContext,
265+
imageCommandContext,
266266
sourceImageResolver,
267267
new ImageContext(httpContext, this.options),
268-
commands,
269268
retry);
270269
}
271270

@@ -278,12 +277,14 @@ private static void SetBadRequest(HttpContext httpContext)
278277
}
279278

280279
private async Task ProcessRequestAsync(
281-
HttpContext httpContext,
280+
ImageCommandContext imageCommandContext,
282281
IImageResolver sourceImageResolver,
283282
ImageContext imageContext,
284-
CommandCollection commands,
285283
bool retry)
286284
{
285+
HttpContext httpContext = imageCommandContext.Context;
286+
CommandCollection commands = imageCommandContext.Commands;
287+
287288
// Create a hashed cache key
288289
string key = this.cacheHash.Create(
289290
this.cacheKey.Create(httpContext, commands),
@@ -344,55 +345,45 @@ private async Task ProcessRequestAsync(
344345
{
345346
DecoderOptions decoderOptions = new() { Configuration = this.options.Configuration };
346347

347-
// TODO: We need some way to set options based upon processors.
348-
await this.options.OnBeforeLoadAsync.Invoke(httpContext, decoderOptions);
348+
// TODO: Do we need some way to set options based upon processors?
349+
await this.options.OnBeforeLoadAsync.Invoke(imageCommandContext, decoderOptions);
349350

350-
// No commands? We simply copy the stream across.
351-
if (commands.Count == 0)
351+
FormattedImage? image = null;
352+
try
352353
{
353-
await inStream.CopyToAsync(outStream);
354-
outStream.Position = 0;
355-
format = await Image.DetectFormatAsync(decoderOptions, outStream);
356-
}
357-
else
358-
{
359-
FormattedImage? image = null;
360-
try
354+
// Now we can finally process the image.
355+
// We first sort the processor collection by command order then use that collection to determine whether the decoded image pixel format
356+
// explicitly requires an alpha component in order to allow correct processing.
357+
//
358+
// The non-generic variant will decode to the correct pixel format based upon the encoded image metadata which can yield
359+
// massive memory savings.
360+
IReadOnlyList<(int Index, IImageWebProcessor Processor)> sortedProcessors = this.processors.OrderBySupportedCommands(commands);
361+
bool requiresAlpha = sortedProcessors.RequiresTrueColorPixelFormat(commands, this.commandParser, this.parserCulture);
362+
363+
if (requiresAlpha)
361364
{
362-
// Now we can finally process the image.
363-
// We first sort the processor collection by command order then use that collection to determine whether the decoded image pixel format
364-
// explicitly requires an alpha component in order to allow correct processing.
365-
//
366-
// The non-generic variant will decode to the correct pixel format based upon the encoded image metadata which can yield
367-
// massive memory savings.
368-
IReadOnlyList<(int Index, IImageWebProcessor Processor)> sortedProcessors = this.processors.OrderBySupportedCommands(commands);
369-
bool requiresAlpha = sortedProcessors.RequiresTrueColorPixelFormat(commands, this.commandParser, this.parserCulture);
370-
371-
if (requiresAlpha)
372-
{
373-
image = await FormattedImage.LoadAsync<Rgba32>(decoderOptions, inStream);
374-
}
375-
else
376-
{
377-
image = await FormattedImage.LoadAsync(decoderOptions, inStream);
378-
}
379-
380-
image.Process(
381-
this.logger,
382-
sortedProcessors,
383-
commands,
384-
this.commandParser,
385-
this.parserCulture);
386-
387-
await this.options.OnBeforeSaveAsync.Invoke(image);
388-
389-
image.Save(outStream);
390-
format = image.Format;
365+
image = await FormattedImage.LoadAsync<Rgba32>(decoderOptions, inStream);
391366
}
392-
finally
367+
else
393368
{
394-
image?.Dispose();
369+
image = await FormattedImage.LoadAsync(decoderOptions, inStream);
395370
}
371+
372+
image.Process(
373+
this.logger,
374+
sortedProcessors,
375+
commands,
376+
this.commandParser,
377+
this.parserCulture);
378+
379+
await this.options.OnBeforeSaveAsync.Invoke(image);
380+
381+
image.Save(outStream);
382+
format = image.Format;
383+
}
384+
finally
385+
{
386+
image?.Dispose();
396387
}
397388
}
398389

src/ImageSharp.Web/Middleware/ImageSharpMiddlewareOptions.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class ImageSharpMiddlewareOptions
2727
};
2828

2929
private Func<ImageCommandContext, Task> onParseCommandsAsync = _ => Task.CompletedTask;
30-
private Func<HttpContext, DecoderOptions, Task> onBeforeLoadAsync = (_, _) => Task.CompletedTask;
30+
private Func<ImageCommandContext, DecoderOptions, Task> onBeforeLoadAsync = (_, _) => Task.CompletedTask;
3131
private Func<FormattedImage, Task> onBeforeSaveAsync = _ => Task.CompletedTask;
3232
private Func<ImageProcessingContext, Task> onProcessedAsync = _ => Task.CompletedTask;
3333
private Func<HttpContext, Task> onPrepareResponseAsync = _ => Task.CompletedTask;
@@ -118,7 +118,7 @@ public Func<ImageCommandContext, Task> OnParseCommandsAsync
118118
/// Gets or sets the method that can be used to used to augment decoder options.
119119
/// This is called before the image is decoded and loaded for processing.
120120
/// </summary>
121-
public Func<HttpContext, DecoderOptions, Task> OnBeforeLoadAsync
121+
public Func<ImageCommandContext, DecoderOptions, Task> OnBeforeLoadAsync
122122
{
123123
get => this.onBeforeLoadAsync;
124124

tests/ImageSharp.Web.Tests/TestUtilities/TestServerFixture.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ protected void ConfigureServices(IServiceCollection services)
6868
return onParseCommandsAsync.Invoke(context);
6969
};
7070

71-
Func<HttpContext, DecoderOptions, Task> onBeforeLoadAsync = options.OnBeforeLoadAsync;
71+
Func<ImageCommandContext, DecoderOptions, Task> onBeforeLoadAsync = options.OnBeforeLoadAsync;
7272

7373
options.OnBeforeLoadAsync = (context, decoderOptions) =>
7474
{

0 commit comments

Comments
 (0)