diff --git a/samples/ImageSharp.Web.Sample/wwwroot/imagesharp-logo.png b/samples/ImageSharp.Web.Sample/wwwroot/imagesharp-logo.png deleted file mode 100644 index 0b661ed7..00000000 --- a/samples/ImageSharp.Web.Sample/wwwroot/imagesharp-logo.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8e0e61e92427f3686cf4558193c077ab0ec78b5c869e90445147c0c67d66ce10 -size 25255 diff --git a/samples/ImageSharp.Web.Sample/wwwroot/index.html b/samples/ImageSharp.Web.Sample/wwwroot/index.html index 53cd06f0..ef3cfa4f 100644 --- a/samples/ImageSharp.Web.Sample/wwwroot/index.html +++ b/samples/ImageSharp.Web.Sample/wwwroot/index.html @@ -44,10 +44,10 @@

ImageSharp URI API Samples

Unmodified

- imagesharp-logo.png + sixlabors.imagesharp.web.png

- +

@@ -55,50 +55,50 @@

Unmodified

Resize

- imagesharp-logo.png?width=300 + sixlabors.imagesharp.web.png?width=300

- +

- imagesharp-logo.png?width=300&height=200 + sixlabors.imagesharp.web.png?width=300&height=200

- +

- imagesharp-logo.png?width=300&height=200&rmode=stretch + sixlabors.imagesharp.web.png?width=300&height=200&rmode=stretch

- +

- imagesharp-logo.png?width=300&height=200&rmode=pad + sixlabors.imagesharp.web.png?width=300&height=200&rmode=pad&rcolor=limegreen

- +

- imagesharp-logo.png?width=300&rsampler=lanczos3 + sixlabors.imagesharp.web.png?width=300&rsampler=lanczos3

- +

- imagesharp-logo.png?width=300&rsampler=nearest + sixlabors.imagesharp.web.png?width=300&rsampler=nearest

- +

@@ -107,34 +107,34 @@

Resize

Format

- imagesharp-logo.png?width=300&format=jpg + sixlabors.imagesharp.web.png?width=300&format=jpg

- +

- imagesharp-logo.png?width=300&format=bmp + sixlabors.imagesharp.web.png?width=300&format=bmp

- +

- imagesharp-logo.png?width=300&format=gif + sixlabors.imagesharp.web.png?width=300&format=gif

- +

- imagesharp-logo.png?width=300&format=webp + sixlabors.imagesharp.web.png?width=300&format=webp

- +

@@ -143,26 +143,26 @@

Format

Jpeg Quality

- imagesharp-logo.png?width=300&format=jpg&quality=100 + sixlabors.imagesharp.web.png?width=300&format=jpg&quality=100

- +

- imagesharp-logo.png?width=300&format=jpg&quality=50 + sixlabors.imagesharp.web.png?width=300&format=jpg&quality=50

- +

- imagesharp-logo.png?width=300&format=jpg&quality=1 + sixlabors.imagesharp.web.png?width=300&format=jpg&quality=1

- +

@@ -171,26 +171,26 @@

Jpeg Quality

Webp Quality

- imagesharp-logo.png?width=300&format=webp&quality=100 + sixlabors.imagesharp.web.png?width=300&format=webp&quality=100

- +

- imagesharp-logo.png?width=300&format=webp&quality=50 + sixlabors.imagesharp.web.png?width=300&format=webp&quality=50

- +

- imagesharp-logo.png?width=300&format=webp&quality=1 + sixlabors.imagesharp.web.png?width=300&format=webp&quality=1

- +

@@ -199,42 +199,42 @@

Webp Quality

Background Color

- imagesharp-logo.png?width=300&bgcolor=red + sixlabors.imagesharp.web.png?width=300&bgcolor=red

- +

- imagesharp-logo.png?width=300&bgcolor=FFFF00 + sixlabors.imagesharp.web.png?width=300&bgcolor=FFFF00

- +

- imagesharp-logo.png?width=300&bgcolor=128,28,32 + sixlabors.imagesharp.web.png?width=300&bgcolor=128,28,32

- +

- imagesharp-logo.png?width=300&bgcolor=C1FF0080 + sixlabors.imagesharp.web.png?width=300&bgcolor=C1FF0080

- +

- imagesharp-logo.png?width=300&bgcolor=128,28,32,128 + sixlabors.imagesharp.web.png?width=300&bgcolor=128,28,32,128

- +

@@ -244,26 +244,26 @@

Identical Queries

Demonstrates that the middleware handles identical queries without file contention.

- imagesharp-logo.png?width=123 + sixlabors.imagesharp.web.png?width=123

- +

- imagesharp-logo.png?width=123 + sixlabors.imagesharp.web.png?width=123

- +

- imagesharp-logo.png?width=123 + sixlabors.imagesharp.web.png?width=123

- +

@@ -394,59 +394,59 @@

EXIF Handling Portrait

Demonstrates that the middleware handles EXIF orientation correctly for portrait images.

- Portrait_0.jpg?width=60&height=50&ranchor=left&rmode=pad + Portrait_0.jpg?width=60&height=50&ranchor=left&rmode=pad&rcolor=limegreen

-

+

- Portrait_1.jpg?width=60&height=50&ranchor=left&rmode=pad + Portrait_1.jpg?width=60&height=50&ranchor=left&rmode=pad&rcolor=limegreen

-

+

- Portrait_2.jpg?width=60&height=50&ranchor=left&rmode=pad + Portrait_2.jpg?width=60&height=50&ranchor=left&rmode=pad&rcolor=limegreen

-

+

- Portrait_3.jpg?width=60&height=50&ranchor=left&rmode=pad + Portrait_3.jpg?width=60&height=50&ranchor=left&rmode=pad&rcolor=limegreen

-

+

- Portrait_4.jpg?width=60&height=50&ranchor=left&rmode=pad + Portrait_4.jpg?width=60&height=50&ranchor=left&rmode=pad&rcolor=limegreen

-

+

- Portrait_5.jpg?width=60&height=50&ranchor=left&rmode=pad + Portrait_5.jpg?width=60&height=50&ranchor=left&rmode=pad&rcolor=limegreen

-

+

- Portrait_6.jpg?width=60&height=50&ranchor=left&rmode=pad + Portrait_6.jpg?width=60&height=50&ranchor=left&rmode=pad&rcolor=limegreen

-

+

- Portrait_7.jpg?width=60&height=50&ranchor=left&rmode=pad + Portrait_7.jpg?width=60&height=50&ranchor=left&rmode=pad&rcolor=limegreen

-

+

- Portrait_8.jpg?width=60&height=50&ranchor=left&rmode=pad + Portrait_8.jpg?width=60&height=50&ranchor=left&rmode=pad&rcolor=limegreen

-

+

@@ -455,59 +455,59 @@

EXIF Handling Portrait

Demonstrates that the middleware handles EXIF orientation correctly for portrait images.

- Portrait_0.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Portrait_0.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Portrait_1.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Portrait_1.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Portrait_2.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Portrait_2.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Portrait_3.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Portrait_3.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Portrait_4.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Portrait_4.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Portrait_5.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Portrait_5.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Portrait_6.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Portrait_6.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Portrait_7.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Portrait_7.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Portrait_8.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Portrait_8.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

@@ -516,59 +516,59 @@

EXIF Handling Portrait

Demonstrates that the middleware handles EXIF orientation correctly for portrait images.

- Portrait_0.jpg?width=60&height=50&ranchor=right&rmode=pad + Portrait_0.jpg?width=60&height=50&ranchor=right&rmode=pad&rcolor=limegreen

-

+

- Portrait_1.jpg?width=60&height=50&ranchor=right&rmode=pad + Portrait_1.jpg?width=60&height=50&ranchor=right&rmode=pad&rcolor=limegreen

-

+

- Portrait_2.jpg?width=60&height=50&ranchor=right&rmode=pad + Portrait_2.jpg?width=60&height=50&ranchor=right&rmode=pad&rcolor=limegreen

-

+

- Portrait_3.jpg?width=60&height=50&ranchor=right&rmode=pad + Portrait_3.jpg?width=60&height=50&ranchor=right&rmode=pad&rcolor=limegreen

-

+

- Portrait_4.jpg?width=60&height=50&ranchor=right&rmode=pad + Portrait_4.jpg?width=60&height=50&ranchor=right&rmode=pad&rcolor=limegreen

-

+

- Portrait_5.jpg?width=60&height=50&ranchor=right&rmode=pad + Portrait_5.jpg?width=60&height=50&ranchor=right&rmode=pad&rcolor=limegreen

-

+

- Portrait_6.jpg?width=60&height=50&ranchor=right&rmode=pad + Portrait_6.jpg?width=60&height=50&ranchor=right&rmode=pad&rcolor=limegreen

-

+

- Portrait_7.jpg?width=60&height=50&ranchor=right&rmode=pad + Portrait_7.jpg?width=60&height=50&ranchor=right&rmode=pad&rcolor=limegreen

-

+

- Portrait_8.jpg?width=60&height=50&ranchor=right&rmode=pad + Portrait_8.jpg?width=60&height=50&ranchor=right&rmode=pad&rcolor=limegreen

-

+

@@ -578,59 +578,59 @@

EXIF Handling Portrait

Demonstrates that the middleware handles EXIF orientation correctly for portrait images.

- Portrait_0.jpg?width=60&height=50&ranchor=bottomright&rmode=pad + Portrait_0.jpg?width=60&height=50&ranchor=bottomright&rmode=pad&rcolor=limegreen

-

+

- Portrait_1.jpg?width=60&height=50&ranchor=bottomright&rmode=pad + Portrait_1.jpg?width=60&height=50&ranchor=bottomright&rmode=pad&rcolor=limegreen

-

+

- Portrait_2.jpg?width=60&height=50&ranchor=bottomright&rmode=pad + Portrait_2.jpg?width=60&height=50&ranchor=bottomright&rmode=pad&rcolor=limegreen

-

+

- Portrait_3.jpg?width=60&height=50&ranchor=bottomright&rmode=pad + Portrait_3.jpg?width=60&height=50&ranchor=bottomright&rmode=pad&rcolor=limegreen

-

+

- Portrait_4.jpg?width=60&height=50&ranchor=bottomright&rmode=pad + Portrait_4.jpg?width=60&height=50&ranchor=bottomright&rmode=pad&rcolor=limegreen

-

+

- Portrait_5.jpg?width=60&height=50&ranchor=bottomright&rmode=pad + Portrait_5.jpg?width=60&height=50&ranchor=bottomright&rmode=pad&rcolor=limegreen

-

+

- Portrait_6.jpg?width=60&height=50&ranchor=bottomright&rmode=pad + Portrait_6.jpg?width=60&height=50&ranchor=bottomright&rmode=pad&rcolor=limegreen

-

+

- Portrait_7.jpg?width=60&height=50&ranchor=bottomright&rmode=pad + Portrait_7.jpg?width=60&height=50&ranchor=bottomright&rmode=pad&rcolor=limegreen

-

+

- Portrait_8.jpg?width=60&height=50&ranchor=bottomright&rmode=pad + Portrait_8.jpg?width=60&height=50&ranchor=bottomright&rmode=pad&rcolor=limegreen

-

+

@@ -761,59 +761,59 @@

EXIF Handling : Landscape

Demonstrates that the middleware handles EXIF orientation correctly for landscape images.

- Landscape_0.jpg?width=60&height=50&ranchor=top&rmode=pad + Landscape_0.jpg?width=60&height=50&ranchor=top&rmode=pad&rcolor=limegreen

-

+

- Landscape_1.jpg?width=60&height=50&ranchor=top&rmode=pad + Landscape_1.jpg?width=60&height=50&ranchor=top&rmode=pad&rcolor=limegreen

-

+

- Landscape_2.jpg?width=60&height=50&ranchor=top&rmode=pad + Landscape_2.jpg?width=60&height=50&ranchor=top&rmode=pad&rcolor=limegreen

-

+

- Landscape_3.jpg?width=60&height=50&ranchor=top&rmode=pad + Landscape_3.jpg?width=60&height=50&ranchor=top&rmode=pad&rcolor=limegreen

-

+

- Landscape_4.jpg?width=60&height=50&ranchor=top&rmode=pad + Landscape_4.jpg?width=60&height=50&ranchor=top&rmode=pad&rcolor=limegreen

-

+

- Landscape_5.jpg?width=60&height=50&ranchor=top&rmode=pad + Landscape_5.jpg?width=60&height=50&ranchor=top&rmode=pad&rcolor=limegreen

-

+

- Landscape_6.jpg?width=60&height=50&ranchor=top&rmode=pad + Landscape_6.jpg?width=60&height=50&ranchor=top&rmode=pad&rcolor=limegreen

-

+

- Landscape_7.jpg?width=60&height=50&ranchor=top&rmode=pad + Landscape_7.jpg?width=60&height=50&ranchor=top&rmode=pad&rcolor=limegreen

-

+

- Landscape_8.jpg?width=60&height=50&ranchor=top&rmode=pad + Landscape_8.jpg?width=60&height=50&ranchor=top&rmode=pad&rcolor=limegreen

-

+

@@ -822,59 +822,59 @@

EXIF Handling : Landscape

Demonstrates that the middleware handles EXIF orientation correctly for landscape images.

- Landscape_0.jpg?width=60&height=50&ranchor=topright&rmode=pad + Landscape_0.jpg?width=60&height=50&ranchor=topright&rmode=pad&rcolor=limegreen

-

+

- Landscape_1.jpg?width=60&height=50&ranchor=topright&rmode=pad + Landscape_1.jpg?width=60&height=50&ranchor=topright&rmode=pad&rcolor=limegreen

-

+

- Landscape_2.jpg?width=60&height=50&ranchor=topright&rmode=pad + Landscape_2.jpg?width=60&height=50&ranchor=topright&rmode=pad&rcolor=limegreen

-

+

- Landscape_3.jpg?width=60&height=50&ranchor=topright&rmode=pad + Landscape_3.jpg?width=60&height=50&ranchor=topright&rmode=pad&rcolor=limegreen

-

+

- Landscape_4.jpg?width=60&height=50&ranchor=topright&rmode=pad + Landscape_4.jpg?width=60&height=50&ranchor=topright&rmode=pad&rcolor=limegreen

-

+

- Landscape_5.jpg?width=60&height=50&ranchor=topright&rmode=pad + Landscape_5.jpg?width=60&height=50&ranchor=topright&rmode=pad&rcolor=limegreen

-

+

- Landscape_6.jpg?width=60&height=50&ranchor=topright&rmode=pad + Landscape_6.jpg?width=60&height=50&ranchor=topright&rmode=pad&rcolor=limegreen

-

+

- Landscape_7.jpg?width=60&height=50&ranchor=topright&rmode=pad + Landscape_7.jpg?width=60&height=50&ranchor=topright&rmode=pad&rcolor=limegreen

-

+

- Landscape_8.jpg?width=60&height=50&ranchor=topright&rmode=pad + Landscape_8.jpg?width=60&height=50&ranchor=topright&rmode=pad&rcolor=limegreen

-

+

@@ -883,59 +883,59 @@

EXIF Handling : Landscape

Demonstrates that the middleware handles EXIF orientation correctly for landscape images.

- Landscape_0.jpg?width=60&height=50&ranchor=bottom&rmode=pad + Landscape_0.jpg?width=60&height=50&ranchor=bottom&rmode=pad&rcolor=limegreen

-

+

- Landscape_1.jpg?width=60&height=50&ranchor=bottom&rmode=pad + Landscape_1.jpg?width=60&height=50&ranchor=bottom&rmode=pad&rcolor=limegreen

-

+

- Landscape_2.jpg?width=60&height=50&ranchor=bottom&rmode=pad + Landscape_2.jpg?width=60&height=50&ranchor=bottom&rmode=pad&rcolor=limegreen

-

+

- Landscape_3.jpg?width=60&height=50&ranchor=bottom&rmode=pad + Landscape_3.jpg?width=60&height=50&ranchor=bottom&rmode=pad&rcolor=limegreen

-

+

- Landscape_4.jpg?width=60&height=50&ranchor=bottom&rmode=pad + Landscape_4.jpg?width=60&height=50&ranchor=bottom&rmode=pad&rcolor=limegreen

-

+

- Landscape_5.jpg?width=60&height=50&ranchor=bottom&rmode=pad + Landscape_5.jpg?width=60&height=50&ranchor=bottom&rmode=pad&rcolor=limegreen

-

+

- Landscape_6.jpg?width=60&height=50&ranchor=bottom&rmode=pad + Landscape_6.jpg?width=60&height=50&ranchor=bottom&rmode=pad&rcolor=limegreen

-

+

- Landscape_7.jpg?width=60&height=50&ranchor=bottom&rmode=pad + Landscape_7.jpg?width=60&height=50&ranchor=bottom&rmode=pad&rcolor=limegreen

-

+

- Landscape_8.jpg?width=60&height=50&ranchor=bottom&rmode=pad + Landscape_8.jpg?width=60&height=50&ranchor=bottom&rmode=pad&rcolor=limegreen

-

+

@@ -944,59 +944,59 @@

EXIF Handling : Landscape

Demonstrates that the middleware handles EXIF orientation correctly for landscape images.

- Landscape_0.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Landscape_0.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Landscape_1.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Landscape_1.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Landscape_2.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Landscape_2.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Landscape_3.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Landscape_3.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Landscape_4.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Landscape_4.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Landscape_5.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Landscape_5.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Landscape_6.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Landscape_6.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Landscape_7.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Landscape_7.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

- Landscape_8.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad + Landscape_8.jpg?width=60&height=50&ranchor=bottomleft&rmode=pad&rcolor=limegreen

-

+

diff --git a/samples/ImageSharp.Web.Sample/wwwroot/sixlabors.imagesharp.web.png b/samples/ImageSharp.Web.Sample/wwwroot/sixlabors.imagesharp.web.png new file mode 100644 index 00000000..d60a4f9c --- /dev/null +++ b/samples/ImageSharp.Web.Sample/wwwroot/sixlabors.imagesharp.web.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e320603ed2376bf6c79180b0e611b08a1c11c4b68856327023ef4af323a55628 +size 18945 diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 2bf03cfd..c2963f9b 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -17,11 +17,7 @@ - - - - diff --git a/src/ImageSharp.Web.Providers.AWS/ImageSharp.Web.Providers.AWS.csproj b/src/ImageSharp.Web.Providers.AWS/ImageSharp.Web.Providers.AWS.csproj index 0310d349..74af6b95 100644 --- a/src/ImageSharp.Web.Providers.AWS/ImageSharp.Web.Providers.AWS.csproj +++ b/src/ImageSharp.Web.Providers.AWS/ImageSharp.Web.Providers.AWS.csproj @@ -31,7 +31,7 @@ - + diff --git a/src/ImageSharp.Web.Providers.Azure/ImageSharp.Web.Providers.Azure.csproj b/src/ImageSharp.Web.Providers.Azure/ImageSharp.Web.Providers.Azure.csproj index 0c16153e..6c746c25 100644 --- a/src/ImageSharp.Web.Providers.Azure/ImageSharp.Web.Providers.Azure.csproj +++ b/src/ImageSharp.Web.Providers.Azure/ImageSharp.Web.Providers.Azure.csproj @@ -31,7 +31,8 @@ - + + diff --git a/src/ImageSharp.Web/Caching/PhysicalFileSystemCache.cs b/src/ImageSharp.Web/Caching/PhysicalFileSystemCache.cs index 7add7ebd..7035b48d 100644 --- a/src/ImageSharp.Web/Caching/PhysicalFileSystemCache.cs +++ b/src/ImageSharp.Web/Caching/PhysicalFileSystemCache.cs @@ -84,7 +84,7 @@ internal static string GetCacheRoot(PhysicalFileSystemCacheOptions cacheOptions, /// public Task GetAsync(string key) { - string path = ToFilePath(key, this.cacheFolderDepth); + string path = Path.Combine(this.cacheRootPath, ToFilePath(key, this.cacheFolderDepth)); var metaFileInfo = new FileInfo(this.ToMetaDataFilePath(path)); if (!metaFileInfo.Exists) diff --git a/src/ImageSharp.Web/FormattedImage.cs b/src/ImageSharp.Web/FormattedImage.cs index c7b273b1..242bdc67 100644 --- a/src/ImageSharp.Web/FormattedImage.cs +++ b/src/ImageSharp.Web/FormattedImage.cs @@ -27,7 +27,7 @@ public sealed class FormattedImage : IDisposable /// /// The image. /// The format. - internal FormattedImage(Image image, IImageFormat format) + internal FormattedImage(Image image, IImageFormat format) { this.Image = image; this.imageFormatsManager = image.GetConfiguration().ImageFormatsManager; @@ -35,9 +35,9 @@ internal FormattedImage(Image image, IImageFormat format) } /// - /// Gets the image. + /// Gets the decoded image. /// - public Image Image { get; private set; } + public Image Image { get; private set; } /// /// Gets or sets the format. @@ -82,41 +82,36 @@ public IImageEncoder Encoder } /// - /// Loads the specified source. + /// Create a new instance of the class from the given stream. /// + /// The pixel format. /// The configuration. /// The source. - /// The . - public static FormattedImage Load(Configuration configuration, Stream source) + /// A representing the asynchronous operation. + internal static async Task LoadAsync(Configuration configuration, Stream source) + where TPixel : unmanaged, IPixel { - var image = ImageSharp.Image.Load(configuration, source, out IImageFormat format); + (Image image, IImageFormat format) = await Image.LoadWithFormatAsync(configuration, source); return new FormattedImage(image, format); } /// - /// Loads the specified source. + /// Create a new instance of the class from the given stream. /// /// The configuration. /// The source. /// A representing the asynchronous operation. - public static async Task LoadAsync(Configuration configuration, Stream source) + internal static async Task LoadAsync(Configuration configuration, Stream source) { - (Image image, IImageFormat format) = await ImageSharp.Image.LoadWithFormatAsync(configuration, source); + (Image image, IImageFormat format) = await Image.LoadWithFormatAsync(configuration, source); return new FormattedImage(image, format); } /// - /// Saves image to the specified destination stream. - /// - /// The destination stream. - public void Save(Stream destination) => this.Image.Save(destination, this.encoder); - - /// - /// Saves image to the specified destination stream. + /// Saves the to the specified destination stream. /// /// The destination stream. - /// A representing the asynchronous operation. - public Task SaveAsync(Stream destination) => this.Image.SaveAsync(destination, this.encoder); + internal void Save(Stream destination) => this.Image.Save(destination, this.encoder); /// /// Gets the EXIF orientation metata for the . diff --git a/src/ImageSharp.Web/ImageSharp.Web.csproj b/src/ImageSharp.Web/ImageSharp.Web.csproj index c100b651..6fb325b6 100644 --- a/src/ImageSharp.Web/ImageSharp.Web.csproj +++ b/src/ImageSharp.Web/ImageSharp.Web.csproj @@ -1,4 +1,4 @@ - + SixLabors.ImageSharp.Web @@ -44,8 +44,8 @@ - - + + diff --git a/src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs b/src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs index bbb6db09..7fac00bc 100644 --- a/src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs +++ b/src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.Options; using Microsoft.IO; using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Web.Caching; using SixLabors.ImageSharp.Web.Commands; using SixLabors.ImageSharp.Web.Processors; @@ -334,19 +335,43 @@ private async Task ProcessRequestAsync( } else { - using FormattedImage image = await FormattedImage.LoadAsync(this.options.Configuration, inStream); - - image.Process( - this.logger, - this.processors, - commands, - this.commandParser, - this.parserCulture); - - await this.options.OnBeforeSaveAsync.Invoke(image); - - image.Save(outStream); - format = image.Format; + FormattedImage image = null; + try + { + // Now we can finally process the image. + // We first sort the processor collection by command order then use that collection to determine whether the decoded image pixel format + // explicitly requires an alpha component in order to allow correct processing. + // + // The non-generic variant will decode to the correct pixel format based upon the encoded image metadata which can yield + // massive memory savings. + IReadOnlyList<(int Index, IImageWebProcessor Processor)> sortedProcessors = this.processors.OrderBySupportedCommands(commands); + bool requiresAlpha = sortedProcessors.RequiresTrueColorPixelFormat(commands, this.commandParser, this.parserCulture); + + if (requiresAlpha) + { + image = await FormattedImage.LoadAsync(this.options.Configuration, inStream); + } + else + { + image = await FormattedImage.LoadAsync(this.options.Configuration, inStream); + } + + image.Process( + this.logger, + sortedProcessors, + commands, + this.commandParser, + this.parserCulture); + + await this.options.OnBeforeSaveAsync.Invoke(image); + + image.Save(outStream); + format = image.Format; + } + finally + { + image?.Dispose(); + } } } diff --git a/src/ImageSharp.Web/Processors/BackgroundColorWebProcessor.cs b/src/ImageSharp.Web/Processors/BackgroundColorWebProcessor.cs index bc596943..bdb505da 100644 --- a/src/ImageSharp.Web/Processors/BackgroundColorWebProcessor.cs +++ b/src/ImageSharp.Web/Processors/BackgroundColorWebProcessor.cs @@ -45,5 +45,8 @@ public FormattedImage Process( return image; } + + /// + public bool RequiresTrueColorPixelFormat(CommandCollection commands, CommandParser parser, CultureInfo culture) => true; } } diff --git a/src/ImageSharp.Web/Processors/FormatWebProcessor.cs b/src/ImageSharp.Web/Processors/FormatWebProcessor.cs index a9036533..f984c746 100644 --- a/src/ImageSharp.Web/Processors/FormatWebProcessor.cs +++ b/src/ImageSharp.Web/Processors/FormatWebProcessor.cs @@ -64,5 +64,8 @@ public FormattedImage Process( return image; } + + /// + public bool RequiresTrueColorPixelFormat(CommandCollection commands, CommandParser parser, CultureInfo culture) => false; } } diff --git a/src/ImageSharp.Web/Processors/IImageWebProcessor.cs b/src/ImageSharp.Web/Processors/IImageWebProcessor.cs index 2393de24..b653e12f 100644 --- a/src/ImageSharp.Web/Processors/IImageWebProcessor.cs +++ b/src/ImageSharp.Web/Processors/IImageWebProcessor.cs @@ -35,5 +35,20 @@ FormattedImage Process( CommandCollection commands, CommandParser parser, CultureInfo culture); + + /// + /// + /// Returns a value indicating whether the image to be processed should be decoded using a 32 bit True Color pixel format - 8 bits per color component + /// plus an 8 bit alpha channel . + /// + /// This method is used to determine whether optimizations can be enabled to reduce memory consumption during processing. + /// + /// The ordered collection containing the processing commands. + /// The command parser use for parting commands. + /// + /// The to use as the current parsing culture. + /// + /// The indicating whether a 32 bit True Color pixel format is required. + bool RequiresTrueColorPixelFormat(CommandCollection commands, CommandParser parser, CultureInfo culture); } } diff --git a/src/ImageSharp.Web/Processors/QualityWebProcessor.cs b/src/ImageSharp.Web/Processors/QualityWebProcessor.cs index 7b91d97a..2cde708b 100644 --- a/src/ImageSharp.Web/Processors/QualityWebProcessor.cs +++ b/src/ImageSharp.Web/Processors/QualityWebProcessor.cs @@ -82,5 +82,8 @@ public FormattedImage Process( return image; } + + /// + public bool RequiresTrueColorPixelFormat(CommandCollection commands, CommandParser parser, CultureInfo culture) => false; } } diff --git a/src/ImageSharp.Web/Processors/ResizeWebProcessor.cs b/src/ImageSharp.Web/Processors/ResizeWebProcessor.cs index 7be7b82d..4a8f10e6 100644 --- a/src/ImageSharp.Web/Processors/ResizeWebProcessor.cs +++ b/src/ImageSharp.Web/Processors/ResizeWebProcessor.cs @@ -47,6 +47,11 @@ public class ResizeWebProcessor : IImageWebProcessor /// public const string Anchor = "ranchor"; + /// + /// The command constant for the resize padding background color. + /// + public const string Color = "rcolor"; + /// /// The command constant for the resize orientation handling mode. /// @@ -67,7 +72,8 @@ private static readonly IEnumerable ResizeCommands Sampler, Anchor, Compand, - Orient + Orient, + Color }; /// @@ -132,10 +138,18 @@ internal static ResizeOptions GetResizeOptions( // Defaults to Bicubic if not set. options.Sampler = GetSampler(commands); + options.PadColor = parser.ParseValue(commands.GetValueOrDefault(Color), culture); return options; } + /// + public bool RequiresTrueColorPixelFormat(CommandCollection commands, CommandParser parser, CultureInfo culture) + { + ResizeMode mode = parser.ParseValue(commands.GetValueOrDefault(Mode), culture); + return mode is ResizeMode.Pad or ResizeMode.BoxPad; + } + private static Size ParseSize( ushort orientation, CommandCollection commands, diff --git a/src/ImageSharp.Web/Processors/WebProcessingExtensions.cs b/src/ImageSharp.Web/Processors/WebProcessingExtensions.cs index 5b402b3a..ad6136f5 100644 --- a/src/ImageSharp.Web/Processors/WebProcessingExtensions.cs +++ b/src/ImageSharp.Web/Processors/WebProcessingExtensions.cs @@ -21,7 +21,7 @@ internal static class WebProcessingExtensions /// The type used for performing logging. /// The collection of available processors. /// The parsed collection of processing commands. - /// The command parser use for parting commands. + /// The command parser use for parting commands. /// /// The to use as the current parsing culture. /// @@ -29,14 +29,14 @@ internal static class WebProcessingExtensions public static FormattedImage Process( this FormattedImage source, ILogger logger, - IEnumerable processors, + IReadOnlyList<(int Index, IImageWebProcessor Processor)> processors, CommandCollection commands, - CommandParser commandParser, + CommandParser parser, CultureInfo culture) { - foreach (IImageWebProcessor processor in processors.GetBySupportedCommands(commands)) + foreach ((int Index, IImageWebProcessor Processor) processor in processors) { - source = processor.Process(source, logger, commands, commandParser, culture); + source = processor.Processor.Process(source, logger, commands, parser, culture); } return source; @@ -50,10 +50,9 @@ public static FormattedImage Process( /// /// The sorted proccessors that supports any of the specified commands. /// - public static IEnumerable GetBySupportedCommands(this IEnumerable processors, CommandCollection commands) + public static IReadOnlyList<(int Index, IImageWebProcessor Processor)> OrderBySupportedCommands(this IEnumerable processors, CommandCollection commands) { - var indexedProcessors = new List<(int Index, IImageWebProcessor Processor)>(); - + List<(int Index, IImageWebProcessor Processor)> indexedProcessors = new(); foreach (IImageWebProcessor processor in processors) { // Get index of first supported command @@ -65,12 +64,7 @@ public static IEnumerable GetBySupportedCommands(this IEnume } indexedProcessors.Sort((x, y) => x.Index.CompareTo(y.Index)); - - // Return sorted processors - foreach ((int _, IImageWebProcessor processor) in indexedProcessors) - { - yield return processor; - } + return indexedProcessors; } /// @@ -93,5 +87,34 @@ public static bool IsSupportedCommand(this IImageWebProcessor processor, string return false; } + + /// + /// + /// Returns a value indicating whether the image to be processed should be decoded using a 32 bit True Color pixel format - 8 bits per color component + /// plus an 8 bit alpha channel . + /// + /// This method is used to determine whether optimizations can be enabled to reduce memory consumption during processing. + /// + /// The collection of ordered processors. + /// The ordered collection containing the processing commands. + /// The command parser use for parting commands. + /// + /// The to use as the current parsing culture. + /// + /// The indicating whether a 32 bit True Color pixel format is required. + public static bool RequiresTrueColorPixelFormat( + this IReadOnlyList<(int Index, IImageWebProcessor Processor)> processors, + CommandCollection commands, + CommandParser parser, + CultureInfo culture) + { + bool requiresAlpha = false; + foreach ((int Index, IImageWebProcessor Processor) processor in processors) + { + requiresAlpha |= processor.Processor.RequiresTrueColorPixelFormat(commands, parser, culture); + } + + return requiresAlpha; + } } } diff --git a/tests/Directory.Build.targets b/tests/Directory.Build.targets index ed77866f..29fe32a8 100644 --- a/tests/Directory.Build.targets +++ b/tests/Directory.Build.targets @@ -18,11 +18,7 @@ - - - -