From be8e065695087d5e989c599da4c3562b994fa66c Mon Sep 17 00:00:00 2001 From: Salih Date: Fri, 20 Oct 2023 17:52:16 +0300 Subject: [PATCH 1/3] Fix resize and compress problem --- .../Volo/Abp/Imaging/ImageCompressor.cs | 23 +++++++++++++++++++ .../Volo/Abp/Imaging/ImageResizer.cs | 23 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageCompressor.cs b/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageCompressor.cs index 11789776c7..e32a7d104e 100644 --- a/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageCompressor.cs +++ b/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageCompressor.cs @@ -28,10 +28,25 @@ public class ImageCompressor : IImageCompressor, ITransientDependency { Check.NotNull(stream, nameof(stream)); + if(!stream.CanRead) + { + return new ImageCompressResult(stream, ImageProcessState.Unsupported); + } + + if(!stream.CanSeek) + { + var memoryStream = new MemoryStream(); + await stream.CopyToAsync(memoryStream, CancellationTokenProvider.FallbackToProvider(cancellationToken)); + SeekToBegin(memoryStream); + stream = memoryStream; + } + foreach (var imageCompressorContributor in ImageCompressorContributors) { var result = await imageCompressorContributor.TryCompressAsync(stream, mimeType, CancellationTokenProvider.FallbackToProvider(cancellationToken)); + SeekToBegin(stream); + if (result.State == ImageProcessState.Unsupported) { continue; @@ -64,4 +79,12 @@ public class ImageCompressor : IImageCompressor, ITransientDependency return new ImageCompressResult(bytes, ImageProcessState.Unsupported); } + + protected virtual void SeekToBegin(Stream stream) + { + if (stream.CanSeek) + { + stream.Seek(0, SeekOrigin.Begin); + } + } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageResizer.cs b/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageResizer.cs index 139fc194dd..4afc879089 100644 --- a/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageResizer.cs +++ b/framework/src/Volo.Abp.Imaging.Abstractions/Volo/Abp/Imaging/ImageResizer.cs @@ -38,9 +38,24 @@ public class ImageResizer : IImageResizer, ITransientDependency ChangeDefaultResizeMode(resizeArgs); + if(!stream.CanRead) + { + return new ImageResizeResult(stream, ImageProcessState.Unsupported); + } + + if(!stream.CanSeek) + { + var memoryStream = new MemoryStream(); + await stream.CopyToAsync(memoryStream, CancellationTokenProvider.FallbackToProvider(cancellationToken)); + SeekToBegin(memoryStream); + stream = memoryStream; + } + foreach (var imageResizerContributor in ImageResizerContributors) { var result = await imageResizerContributor.TryResizeAsync(stream, resizeArgs, mimeType, CancellationTokenProvider.FallbackToProvider(cancellationToken)); + + SeekToBegin(stream); if (result.State == ImageProcessState.Unsupported) { @@ -85,4 +100,12 @@ public class ImageResizer : IImageResizer, ITransientDependency resizeArgs.Mode = ImageResizeOptions.DefaultResizeMode; } } + + protected virtual void SeekToBegin(Stream stream) + { + if (stream.CanSeek) + { + stream.Seek(0, SeekOrigin.Begin); + } + } } \ No newline at end of file From 1cf0dbe68597dd09359ac92a136e09eb065ed3b5 Mon Sep 17 00:00:00 2001 From: Salih Date: Fri, 20 Oct 2023 18:05:14 +0300 Subject: [PATCH 2/3] Update Image-Manipulation.md --- docs/en/Image-Manipulation.md | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/docs/en/Image-Manipulation.md b/docs/en/Image-Manipulation.md index 1050b6005e..e1715722aa 100644 --- a/docs/en/Image-Manipulation.md +++ b/docs/en/Image-Manipulation.md @@ -76,8 +76,8 @@ public interface IImageResizer **Example usage:** ```csharp -var result = await _imageResizer.ResizeAsync( - stream, /* A stream object that represents an image */ +var resizeResult = await _imageResizer.ResizeAsync( + imageStream, /* A stream object that represents an image */ new ImageResizeArgs { Width = 100, @@ -88,6 +88,16 @@ var result = await _imageResizer.ResizeAsync( ); ``` +> If `resizeResult.State` returns 'Done,' it means that the resize operation was successful. However, if it does not return 'Done,' the stream you're using might be corrupt. Therefore, you can perform a check like the one below and assign the correct stream to the main stream. + +```csharp +if (resizeResult.Result is not null && imageStream != resizeResult.Result && resizeResult.Result.CanRead) +{ + await imageStream.DisposeAsync(); + imageStream = resizeResult.Result; +} +``` + > You can use `MimeTypes.Image.Jpeg` constant instead of the `image/jpeg` magic string used in that example. ### ImageResizeArgs @@ -170,12 +180,23 @@ public interface IImageCompressor **Example usage:** ```csharp -var result = await _imageCompressor.CompressAsync( - stream, /* A stream object that represents an image */ +var compressResult = await _imageCompressor.CompressAsync( + imageStream, /* A stream object that represents an image */ mimeType: "image/jpeg" ); ``` +> If `compressResult.State` returns 'Done,' it means that the compress operation was successful. However, if it does not return 'Done,' the stream you're using might be corrupt. Therefore, you can perform a check like the one below and assign the correct stream to the main stream. + +```csharp + +if (compressResult.Result is not null && imageStream != compressResult.Result && compressResult.Result.CanRead) +{ + await imageStream.DisposeAsync(); + imageStream = compressResult.Result; +} +``` + ### ImageCompressResult The `ImageCompressResult` is a generic class that is used to return the result of the image compression operations. It has the following properties: From dbf46c481b519baa63f9246403bfb082b7fc2bf5 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Mon, 23 Oct 2023 11:12:20 +0300 Subject: [PATCH 3/3] Update Image-Manipulation.md --- docs/en/Image-Manipulation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/Image-Manipulation.md b/docs/en/Image-Manipulation.md index e1715722aa..9d946e31dd 100644 --- a/docs/en/Image-Manipulation.md +++ b/docs/en/Image-Manipulation.md @@ -88,7 +88,7 @@ var resizeResult = await _imageResizer.ResizeAsync( ); ``` -> If `resizeResult.State` returns 'Done,' it means that the resize operation was successful. However, if it does not return 'Done,' the stream you're using might be corrupt. Therefore, you can perform a check like the one below and assign the correct stream to the main stream. +> **Note:** If `resizeResult.State` returns 'Done', then it means that the resize operation was successful. However, if it returns any other state than 'Done', the stream you're using might be corrupted. Therefore, you can perform a check like the one below and assign the correct stream to the main stream: ```csharp if (resizeResult.Result is not null && imageStream != resizeResult.Result && resizeResult.Result.CanRead) @@ -186,7 +186,7 @@ var compressResult = await _imageCompressor.CompressAsync( ); ``` -> If `compressResult.State` returns 'Done,' it means that the compress operation was successful. However, if it does not return 'Done,' the stream you're using might be corrupt. Therefore, you can perform a check like the one below and assign the correct stream to the main stream. +> **Note:** If `compressResult.State` returns 'Done', then it means that the compression operation was successful. However, if it returns any other state than 'Done', the stream you're using might be corrupted. Therefore, you can perform a check like the one below and assign the correct stream to the main stream: ```csharp