|
|
|
@ -2,6 +2,7 @@ |
|
|
|
// Licensed under the Apache License, Version 2.0.
|
|
|
|
|
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Drawing; |
|
|
|
using System.Drawing.Drawing2D; |
|
|
|
using System.Drawing.Imaging; |
|
|
|
@ -9,6 +10,7 @@ using System.IO; |
|
|
|
using System.Linq; |
|
|
|
using System.Runtime.CompilerServices; |
|
|
|
using System.Runtime.InteropServices; |
|
|
|
using System.Threading; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using ImageMagick; |
|
|
|
using PhotoSauce.MagicScaler; |
|
|
|
@ -124,6 +126,32 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave |
|
|
|
new ParallelOptions { MaxDegreeOfParallelism = this.MaxDegreeOfParallelism }, |
|
|
|
action); |
|
|
|
|
|
|
|
public Task ForEachImageParallelAsync(Func<string, Task> action) |
|
|
|
{ |
|
|
|
int maxDegreeOfParallelism = this.MaxDegreeOfParallelism > 0 |
|
|
|
? this.MaxDegreeOfParallelism |
|
|
|
: Environment.ProcessorCount; |
|
|
|
int partitionSize = (int)Math.Ceiling((double)this.Images.Length / maxDegreeOfParallelism); |
|
|
|
|
|
|
|
List<Task> tasks = new(); |
|
|
|
for (int i = 0; i < this.Images.Length; i += partitionSize) |
|
|
|
{ |
|
|
|
int end = Math.Min(i + partitionSize, this.Images.Length); |
|
|
|
Task task = RunPartition(i, end); |
|
|
|
tasks.Add(task); |
|
|
|
} |
|
|
|
|
|
|
|
return Task.WhenAll(tasks); |
|
|
|
|
|
|
|
Task RunPartition(int start, int end) => Task.Run(async () => |
|
|
|
{ |
|
|
|
for (int i = start; i < end; i++) |
|
|
|
{ |
|
|
|
await action(this.Images[i]); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
private void LogImageProcessed(int width, int height) |
|
|
|
{ |
|
|
|
this.LastProcessedImageSize = new Size(width, height); |
|
|
|
@ -197,6 +225,26 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave |
|
|
|
image.Save(output, this.imageSharpJpegEncoder); |
|
|
|
} |
|
|
|
|
|
|
|
public async Task ImageSharpResizeAsync(string input) |
|
|
|
{ |
|
|
|
using FileStream output = File.Open(this.OutputPath(input), FileMode.Create); |
|
|
|
// Resize it to fit a 150x150 square
|
|
|
|
using var image = await ImageSharpImage.LoadAsync(input); |
|
|
|
this.LogImageProcessed(image.Width, image.Height); |
|
|
|
|
|
|
|
image.Mutate(i => i.Resize(new ResizeOptions |
|
|
|
{ |
|
|
|
Size = new ImageSharpSize(this.ThumbnailSize, this.ThumbnailSize), |
|
|
|
Mode = ResizeMode.Max |
|
|
|
})); |
|
|
|
|
|
|
|
// Reduce the size of the file
|
|
|
|
image.Metadata.ExifProfile = null; |
|
|
|
|
|
|
|
// Save the results
|
|
|
|
await image.SaveAsync(output, this.imageSharpJpegEncoder); |
|
|
|
} |
|
|
|
|
|
|
|
public void MagickResize(string input) |
|
|
|
{ |
|
|
|
using var image = new MagickImage(input); |
|
|
|
|