|
|
|
@ -6,9 +6,12 @@ using System.Diagnostics; |
|
|
|
using System.IO; |
|
|
|
using System.Reflection; |
|
|
|
using System.Threading; |
|
|
|
using PhotoSauce.MagicScaler; |
|
|
|
using PhotoSauce.MagicScaler.Interpolators; |
|
|
|
using SixLabors.ImageSharp.Formats.Jpeg; |
|
|
|
using SixLabors.ImageSharp.PixelFormats; |
|
|
|
using SixLabors.ImageSharp.Processing; |
|
|
|
using SixLabors.ImageSharp.Processing.Processors.Transforms; |
|
|
|
using SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations; |
|
|
|
using SixLabors.ImageSharp.Tests.ProfilingBenchmarks; |
|
|
|
using Xunit.Abstractions; |
|
|
|
@ -28,29 +31,60 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox |
|
|
|
public void WriteLine(string format, params object[] args) => Console.WriteLine(format, args); |
|
|
|
} |
|
|
|
|
|
|
|
public static void Main(string[] args) |
|
|
|
{ |
|
|
|
//ReEncodeImage("Calliphora");
|
|
|
|
const string pathTemplate = ...""; |
|
|
|
|
|
|
|
// DecodeImageResize__explicit("Calliphora", new Size(101, 150));
|
|
|
|
// DecodeImageResize__experimental("Calliphora_aligned_size", new Size(101, 150));
|
|
|
|
//DecodeImageResize__experimental("winter420_noninterleaved", new Size(80, 120));
|
|
|
|
// Second pass - must be 5% smaller than appropriate IDCT scaled size
|
|
|
|
const float scale = 0.75f; |
|
|
|
readonly IResampler resampler = KnownResamplers.Box; |
|
|
|
|
|
|
|
// Decode-Resize-Encode w/ Mutate()
|
|
|
|
// Elapsed: 2504ms across 250 iterations
|
|
|
|
// Average: 10,016ms
|
|
|
|
BenchmarkResizingLoop__explicit("Calliphora", new Size(80, 120), 250); |
|
|
|
|
|
|
|
// Decode-Resize-Encode w/ downscaling decoder
|
|
|
|
// Elapsed: 1157ms across 250 iterations
|
|
|
|
// Average: 4,628ms
|
|
|
|
BenchmarkResizingLoop__experimental("Calliphora", new Size(80, 120), 250); |
|
|
|
public static void Main(string[] args) |
|
|
|
{ |
|
|
|
//ReEncodeImage("jpeg444");
|
|
|
|
|
|
|
|
//Size targetSize = new Size(808, 1200);
|
|
|
|
|
|
|
|
// 808 x 1200
|
|
|
|
// 404 x 600
|
|
|
|
// 202 x 300
|
|
|
|
// 101 x 150
|
|
|
|
string imageName = "Calliphora_aligned_size"; |
|
|
|
|
|
|
|
// Exact matches for 8/4/2/1 scaling
|
|
|
|
//Size exactSizeX8 = new Size(808, 1200);
|
|
|
|
//Size exactSizeX4 = new Size(404, 600);
|
|
|
|
//Size exactSizeX2 = new Size(202, 300);
|
|
|
|
//Size exactSizeX1 = new Size(101, 150);
|
|
|
|
//ReencodeImageResize__experimental(imageName, exactSizeX8);
|
|
|
|
//ReencodeImageResize__experimental(imageName, exactSizeX4);
|
|
|
|
//ReencodeImageResize__experimental(imageName, exactSizeX2);
|
|
|
|
//ReencodeImageResize__experimental(imageName, exactSizeX1);
|
|
|
|
|
|
|
|
Size secondPassSizeX8 = new Size((int)(808 * scale), (int)(1200 * scale)); |
|
|
|
Size secondPassSizeX4 = new Size((int)(404 * scale), (int)(600 * scale)); |
|
|
|
Size secondPassSizeX2 = new Size((int)(202 * scale), (int)(300 * scale)); |
|
|
|
Size secondPassSizeX1 = new Size((int)(101 * scale), (int)(150 * scale)); |
|
|
|
ReencodeImageResize__experimental(imageName, secondPassSizeX8); |
|
|
|
ReencodeImageResize__experimental(imageName, secondPassSizeX4); |
|
|
|
ReencodeImageResize__experimental(imageName, secondPassSizeX2); |
|
|
|
ReencodeImageResize__experimental(imageName, secondPassSizeX1); |
|
|
|
ReencodeImageResize__explicit(imageName, secondPassSizeX8, resampler); |
|
|
|
ReencodeImageResize__explicit(imageName, secondPassSizeX4, resampler); |
|
|
|
ReencodeImageResize__explicit(imageName, secondPassSizeX2, resampler); |
|
|
|
ReencodeImageResize__explicit(imageName, secondPassSizeX1, resampler); |
|
|
|
|
|
|
|
// 'native' resizing - only jpeg dct downscaling
|
|
|
|
//ReencodeImageResize_Comparison("Calliphora_ratio1", targetSize, 100);
|
|
|
|
|
|
|
|
// 'native' + software resizing - jpeg dct downscaling + postprocessing
|
|
|
|
//ReencodeImageResize_Comparison("Calliphora_aligned_size", new Size(269, 400), 99);
|
|
|
|
|
|
|
|
//var benchmarkSize = new Size(404, 600);
|
|
|
|
//BenchmarkResizingLoop__explicit("jpeg_quality_100", benchmarkSize, 300);
|
|
|
|
//BenchmarkResizingLoop__experimental("jpeg_quality_100", benchmarkSize, 300);
|
|
|
|
|
|
|
|
Console.WriteLine("Done."); |
|
|
|
} |
|
|
|
|
|
|
|
const string pathTemplate = "C:\\Users\\pl4nu\\Downloads\\{0}.jpg"; |
|
|
|
|
|
|
|
private static void BenchmarkEncoder(string fileName, int iterations, int quality, JpegColorType color) |
|
|
|
{ |
|
|
|
string loadPath = String.Format(pathTemplate, fileName); |
|
|
|
@ -174,10 +208,10 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox |
|
|
|
img.SaveAsJpeg(savePath, encoder); |
|
|
|
} |
|
|
|
|
|
|
|
private static void DecodeImageResize__explicit(string fileName, Size targetSize, int? quality = null) |
|
|
|
private static void ReencodeImageResize__explicit(string fileName, Size targetSize, IResampler sampler, int? quality = null) |
|
|
|
{ |
|
|
|
string loadPath = String.Format(pathTemplate, fileName); |
|
|
|
string savePath = String.Format(pathTemplate, $"q{quality}_test_{fileName}"); |
|
|
|
string savePath = String.Format(pathTemplate, $"is_res_{sampler.GetType().Name}[{targetSize.Width}x{targetSize.Height}]_{fileName}"); |
|
|
|
|
|
|
|
var decoder = new JpegDecoder(); |
|
|
|
var encoder = new JpegEncoder() |
|
|
|
@ -187,19 +221,18 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox |
|
|
|
}; |
|
|
|
|
|
|
|
using Image img = decoder.Decode<Rgb24>(Configuration.Default, File.OpenRead(loadPath), CancellationToken.None); |
|
|
|
img.Mutate(ctx => ctx.Resize(targetSize, KnownResamplers.Box, false)); |
|
|
|
img.Mutate(ctx => ctx.Resize(targetSize, sampler, compand: false)); |
|
|
|
img.SaveAsJpeg(savePath, encoder); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
private static void DecodeImageResize__experimental(string fileName, Size targetSize, int? quality = null) |
|
|
|
private static void ReencodeImageResize__experimental(string fileName, Size targetSize, int? quality = null) |
|
|
|
{ |
|
|
|
string loadPath = String.Format(pathTemplate, fileName); |
|
|
|
string savePath = String.Format(pathTemplate, $"is_res_jpeg[{targetSize.Width}x{targetSize.Height}]_{fileName}"); |
|
|
|
|
|
|
|
var decoder = new JpegDecoder(); |
|
|
|
var decoder = new JpegDecoder { IgnoreMetadata = true }; |
|
|
|
using Image img = decoder.Experimental__DecodeInto<Rgb24>(Configuration.Default, File.OpenRead(loadPath), targetSize, CancellationToken.None); |
|
|
|
|
|
|
|
string savePath = String.Format(pathTemplate, $"q{quality}_test_{fileName}"); |
|
|
|
var encoder = new JpegEncoder() |
|
|
|
{ |
|
|
|
Quality = quality, |
|
|
|
@ -208,6 +241,45 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox |
|
|
|
img.SaveAsJpeg(savePath, encoder); |
|
|
|
} |
|
|
|
|
|
|
|
private static void ReencodeImageResize__Netvips(string fileName, Size targetSize, int? quality) |
|
|
|
{ |
|
|
|
string loadPath = String.Format(pathTemplate, fileName); |
|
|
|
string savePath = String.Format(pathTemplate, $"netvips_resize_{fileName}"); |
|
|
|
|
|
|
|
using var thumb = NetVips.Image.Thumbnail(loadPath, targetSize.Width, targetSize.Height); |
|
|
|
|
|
|
|
// Save the results
|
|
|
|
thumb.Jpegsave(savePath, q: quality, strip: true, subsampleMode: NetVips.Enums.ForeignSubsample.Off); |
|
|
|
} |
|
|
|
|
|
|
|
private static void ReencodeImageResize__MagicScaler(string fileName, Size targetSize, int quality) |
|
|
|
{ |
|
|
|
string loadPath = String.Format(pathTemplate, fileName); |
|
|
|
string savePath = String.Format(pathTemplate, $"magicscaler_resize_{fileName}"); |
|
|
|
|
|
|
|
var settings = new ProcessImageSettings() |
|
|
|
{ |
|
|
|
Width = targetSize.Width, |
|
|
|
Height = targetSize.Height, |
|
|
|
SaveFormat = FileFormat.Jpeg, |
|
|
|
JpegQuality = quality, |
|
|
|
JpegSubsampleMode = ChromaSubsampleMode.Subsample444, |
|
|
|
Sharpen = false, |
|
|
|
ColorProfileMode = ColorProfileMode.Ignore, |
|
|
|
HybridMode = HybridScaleMode.Turbo, |
|
|
|
}; |
|
|
|
|
|
|
|
using var output = new FileStream(savePath, FileMode.Create); |
|
|
|
MagicImageProcessor.ProcessImage(loadPath, output, settings); |
|
|
|
} |
|
|
|
|
|
|
|
private static void ReencodeImageResize_Comparison(string fileName, Size targetSize, int quality) |
|
|
|
{ |
|
|
|
ReencodeImageResize__experimental(fileName, targetSize, quality); |
|
|
|
ReencodeImageResize__Netvips(fileName, targetSize, quality); |
|
|
|
ReencodeImageResize__MagicScaler(fileName, targetSize, quality); |
|
|
|
} |
|
|
|
|
|
|
|
private static Version GetNetCoreVersion() |
|
|
|
{ |
|
|
|
Assembly assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly; |
|
|
|
|