Use Magick instead of ImageSharp
Support more formats and output in original format (1/10)
This commit is contained in:
parent
55b437d830
commit
35d6a907f6
@ -11,21 +11,14 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="LibHeifSharp" Version="3.2.0" />
|
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="14.0.0" />
|
||||||
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
|
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="aom.dll">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Update="dav1d.dll">
|
<None Update="dav1d.dll">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="libde265.dll">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Update="libheif.dll">
|
<None Update="libheif.dll">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
@ -44,9 +37,6 @@
|
|||||||
<None Update="libs\libx265.dll">
|
<None Update="libs\libx265.dll">
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="libx265.dll">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
116
Comic_Compressor/JxlCompressor.cs
Normal file
116
Comic_Compressor/JxlCompressor.cs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.Formats.Webp;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using ShellProgressBar;
|
||||||
|
|
||||||
|
namespace Comic_Compressor
|
||||||
|
{
|
||||||
|
internal class JxlCompressor
|
||||||
|
{
|
||||||
|
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount)
|
||||||
|
{
|
||||||
|
// Step 1: Get all subdirectories and store them in a list
|
||||||
|
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
int totalFiles = 0;
|
||||||
|
foreach (string subdirectory in subdirectories)
|
||||||
|
{
|
||||||
|
totalFiles += GetImageFiles(subdirectory).Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var progressBar = new ShellProgressBar.ProgressBar(totalFiles, "Compressing images", new ProgressBarOptions
|
||||||
|
{
|
||||||
|
ProgressCharacter = '─',
|
||||||
|
ProgressBarOnBottom = true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Step 2: Iterate through each subdirectory in order
|
||||||
|
foreach (string subdirectory in subdirectories)
|
||||||
|
{
|
||||||
|
// Step 3: Process each directory
|
||||||
|
ProcessDirectory(subdirectory, sourceImagePath, targetStoragePath, progressBar, threadCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("All directories processed successfully.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ProcessDirectory(string subdirectory, string sourceImagePath, string targetStoragePath, ShellProgressBar.ProgressBar progressBar, int threadCount)
|
||||||
|
{
|
||||||
|
// Get the relative path of the subdirectory
|
||||||
|
string relativePath = Path.GetRelativePath(sourceImagePath, subdirectory);
|
||||||
|
|
||||||
|
// Create the corresponding subdirectory in the target storage path
|
||||||
|
string targetSubdirectory = Path.Combine(targetStoragePath, relativePath);
|
||||||
|
Directory.CreateDirectory(targetSubdirectory);
|
||||||
|
|
||||||
|
// Get all image files in the subdirectory (jpg and png)
|
||||||
|
string[] imageFiles = GetImageFiles(subdirectory);
|
||||||
|
|
||||||
|
// Set up ParallelOptions to limit the number of concurrent threads
|
||||||
|
ParallelOptions options = new()
|
||||||
|
{
|
||||||
|
MaxDegreeOfParallelism = threadCount // Adjust this value to set the number of concurrent threads
|
||||||
|
};
|
||||||
|
|
||||||
|
// Process each image file in parallel
|
||||||
|
Parallel.ForEach(imageFiles, options, imageFile =>
|
||||||
|
{
|
||||||
|
// Set the target file path with the .webp extension
|
||||||
|
string targetFilePath = Path.Combine(targetSubdirectory, Path.GetFileNameWithoutExtension(imageFile) + ".webp");
|
||||||
|
|
||||||
|
// Check if the target file already exists
|
||||||
|
if (!File.Exists(targetFilePath))
|
||||||
|
{
|
||||||
|
CompressImage(imageFile, targetFilePath);
|
||||||
|
|
||||||
|
// Update progress bar safely
|
||||||
|
lock (progressBar)
|
||||||
|
{
|
||||||
|
progressBar.Tick($"Processed {Path.GetFileName(imageFile)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (progressBar) { progressBar.Tick($"Skipped {Path.GetFileName(imageFile)}"); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string[] GetImageFiles(string directoryPath)
|
||||||
|
{
|
||||||
|
// Get all image files supported by ImageSharp
|
||||||
|
string[] supportedExtensions = ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.tiff", "*.gif"];
|
||||||
|
List<string> allFiles = [];
|
||||||
|
|
||||||
|
foreach (string extension in supportedExtensions)
|
||||||
|
{
|
||||||
|
allFiles.AddRange(Directory.GetFiles(directoryPath, extension, SearchOption.TopDirectoryOnly));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [.. allFiles];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CompressImage(string sourceFilePath, string targetFilePath)
|
||||||
|
{
|
||||||
|
using SixLabors.ImageSharp.Image image = SixLabors.ImageSharp.Image.Load(sourceFilePath);
|
||||||
|
// Check the longest side of the image and resize if necessary
|
||||||
|
int maxDimension = Math.Max(image.Width, image.Height);
|
||||||
|
if (maxDimension > 1200)
|
||||||
|
{
|
||||||
|
double scaleFactor = 1200.0 / maxDimension;
|
||||||
|
int newWidth = (int)(image.Width * scaleFactor);
|
||||||
|
int newHeight = (int)(image.Height * scaleFactor);
|
||||||
|
image.Mutate(x => x.Resize(newWidth, newHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the image as WebP with a quality level of 85 (for lossy compression)
|
||||||
|
var encoder = new WebpEncoder
|
||||||
|
{
|
||||||
|
Quality = 90,
|
||||||
|
FileFormat = WebpFileFormatType.Lossy
|
||||||
|
};
|
||||||
|
|
||||||
|
image.Save(targetFilePath, encoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
116
Comic_Compressor/LegacyFormatCompressor.cs
Normal file
116
Comic_Compressor/LegacyFormatCompressor.cs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.Formats.Webp;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using ShellProgressBar;
|
||||||
|
|
||||||
|
namespace Comic_Compressor
|
||||||
|
{
|
||||||
|
internal class LegacyFormatCompressor
|
||||||
|
{
|
||||||
|
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount, int targetFormat)
|
||||||
|
{
|
||||||
|
// Step 1: Get all subdirectories and store them in a list
|
||||||
|
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
int totalFiles = 0;
|
||||||
|
foreach (string subdirectory in subdirectories)
|
||||||
|
{
|
||||||
|
totalFiles += GetImageFiles(subdirectory).Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var progressBar = new ShellProgressBar.ProgressBar(totalFiles, "Compressing images", new ProgressBarOptions
|
||||||
|
{
|
||||||
|
ProgressCharacter = '─',
|
||||||
|
ProgressBarOnBottom = true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Step 2: Iterate through each subdirectory in order
|
||||||
|
foreach (string subdirectory in subdirectories)
|
||||||
|
{
|
||||||
|
// Step 3: Process each directory
|
||||||
|
ProcessDirectory(subdirectory, sourceImagePath, targetStoragePath, progressBar, threadCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("All directories processed successfully.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ProcessDirectory(string subdirectory, string sourceImagePath, string targetStoragePath, ShellProgressBar.ProgressBar progressBar, int threadCount)
|
||||||
|
{
|
||||||
|
// Get the relative path of the subdirectory
|
||||||
|
string relativePath = Path.GetRelativePath(sourceImagePath, subdirectory);
|
||||||
|
|
||||||
|
// Create the corresponding subdirectory in the target storage path
|
||||||
|
string targetSubdirectory = Path.Combine(targetStoragePath, relativePath);
|
||||||
|
Directory.CreateDirectory(targetSubdirectory);
|
||||||
|
|
||||||
|
// Get all image files in the subdirectory (jpg and png)
|
||||||
|
string[] imageFiles = GetImageFiles(subdirectory);
|
||||||
|
|
||||||
|
// Set up ParallelOptions to limit the number of concurrent threads
|
||||||
|
ParallelOptions options = new()
|
||||||
|
{
|
||||||
|
MaxDegreeOfParallelism = threadCount // Adjust this value to set the number of concurrent threads
|
||||||
|
};
|
||||||
|
|
||||||
|
// Process each image file in parallel
|
||||||
|
Parallel.ForEach(imageFiles, options, imageFile =>
|
||||||
|
{
|
||||||
|
// Set the target file path with the .webp extension
|
||||||
|
string targetFilePath = Path.Combine(targetSubdirectory, Path.GetFileNameWithoutExtension(imageFile) + ".webp");
|
||||||
|
|
||||||
|
// Check if the target file already exists
|
||||||
|
if (!File.Exists(targetFilePath))
|
||||||
|
{
|
||||||
|
CompressImage(imageFile, targetFilePath);
|
||||||
|
|
||||||
|
// Update progress bar safely
|
||||||
|
lock (progressBar)
|
||||||
|
{
|
||||||
|
progressBar.Tick($"Processed {Path.GetFileName(imageFile)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (progressBar) { progressBar.Tick($"Skipped {Path.GetFileName(imageFile)}"); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string[] GetImageFiles(string directoryPath)
|
||||||
|
{
|
||||||
|
// Get all image files supported by ImageSharp
|
||||||
|
string[] supportedExtensions = ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.tiff", "*.gif"];
|
||||||
|
List<string> allFiles = [];
|
||||||
|
|
||||||
|
foreach (string extension in supportedExtensions)
|
||||||
|
{
|
||||||
|
allFiles.AddRange(Directory.GetFiles(directoryPath, extension, SearchOption.TopDirectoryOnly));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [.. allFiles];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CompressImage(string sourceFilePath, string targetFilePath)
|
||||||
|
{
|
||||||
|
using SixLabors.ImageSharp.Image image = SixLabors.ImageSharp.Image.Load(sourceFilePath);
|
||||||
|
// Check the longest side of the image and resize if necessary
|
||||||
|
int maxDimension = Math.Max(image.Width, image.Height);
|
||||||
|
if (maxDimension > 1200)
|
||||||
|
{
|
||||||
|
double scaleFactor = 1200.0 / maxDimension;
|
||||||
|
int newWidth = (int)(image.Width * scaleFactor);
|
||||||
|
int newHeight = (int)(image.Height * scaleFactor);
|
||||||
|
image.Mutate(x => x.Resize(newWidth, newHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the image as WebP with a quality level of 85 (for lossy compression)
|
||||||
|
var encoder = new WebpEncoder
|
||||||
|
{
|
||||||
|
Quality = 90,
|
||||||
|
FileFormat = WebpFileFormatType.Lossy
|
||||||
|
};
|
||||||
|
|
||||||
|
image.Save(targetFilePath, encoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
111
Comic_Compressor/MixProcessor.cs
Normal file
111
Comic_Compressor/MixProcessor.cs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
namespace Comic_Compressor
|
||||||
|
{
|
||||||
|
internal class MixProcessor
|
||||||
|
{
|
||||||
|
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount, int targetFormat)
|
||||||
|
{
|
||||||
|
// Step 1: Get all subdirectories and store them in a list
|
||||||
|
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
int totalFiles = 0;
|
||||||
|
foreach (string subdirectory in subdirectories)
|
||||||
|
{
|
||||||
|
totalFiles += GetImageFiles(subdirectory).Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var progressBar = new ShellProgressBar.ProgressBar(totalFiles, "Compressing images", new ProgressBarOptions
|
||||||
|
{
|
||||||
|
ProgressCharacter = '─',
|
||||||
|
ProgressBarOnBottom = true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Step 2: Iterate through each subdirectory in order
|
||||||
|
foreach (string subdirectory in subdirectories)
|
||||||
|
{
|
||||||
|
// Step 3: Process each directory
|
||||||
|
ProcessDirectory(subdirectory, sourceImagePath, targetStoragePath, progressBar, threadCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("All directories processed successfully.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ProcessDirectory(string subdirectory, string sourceImagePath, string targetStoragePath, ShellProgressBar.ProgressBar progressBar, int threadCount)
|
||||||
|
{
|
||||||
|
// Get the relative path of the subdirectory
|
||||||
|
string relativePath = Path.GetRelativePath(sourceImagePath, subdirectory);
|
||||||
|
|
||||||
|
// Create the corresponding subdirectory in the target storage path
|
||||||
|
string targetSubdirectory = Path.Combine(targetStoragePath, relativePath);
|
||||||
|
Directory.CreateDirectory(targetSubdirectory);
|
||||||
|
|
||||||
|
// Get all image files in the subdirectory (jpg and png)
|
||||||
|
string[] imageFiles = GetImageFiles(subdirectory);
|
||||||
|
|
||||||
|
// Set up ParallelOptions to limit the number of concurrent threads
|
||||||
|
ParallelOptions options = new()
|
||||||
|
{
|
||||||
|
MaxDegreeOfParallelism = threadCount // Adjust this value to set the number of concurrent threads
|
||||||
|
};
|
||||||
|
|
||||||
|
// Process each image file in parallel
|
||||||
|
Parallel.ForEach(imageFiles, options, imageFile =>
|
||||||
|
{
|
||||||
|
// Set the target file path with the .webp extension
|
||||||
|
string targetFilePath = Path.Combine(targetSubdirectory, Path.GetFileNameWithoutExtension(imageFile) + ".webp");
|
||||||
|
|
||||||
|
// Check if the target file already exists
|
||||||
|
if (!File.Exists(targetFilePath))
|
||||||
|
{
|
||||||
|
CompressImage(imageFile, targetFilePath);
|
||||||
|
|
||||||
|
// Update progress bar safely
|
||||||
|
lock (progressBar)
|
||||||
|
{
|
||||||
|
progressBar.Tick($"Processed {Path.GetFileName(imageFile)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (progressBar) { progressBar.Tick($"Skipped {Path.GetFileName(imageFile)}"); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string[] GetImageFiles(string directoryPath)
|
||||||
|
{
|
||||||
|
// Get all image files supported by ImageSharp
|
||||||
|
string[] supportedExtensions = ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.tiff", "*.gif"];
|
||||||
|
List<string> allFiles = [];
|
||||||
|
|
||||||
|
foreach (string extension in supportedExtensions)
|
||||||
|
{
|
||||||
|
allFiles.AddRange(Directory.GetFiles(directoryPath, extension, SearchOption.TopDirectoryOnly));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [.. allFiles];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CompressImage(string sourceFilePath, string targetFilePath)
|
||||||
|
{
|
||||||
|
using SixLabors.ImageSharp.Image image = SixLabors.ImageSharp.Image.Load(sourceFilePath);
|
||||||
|
// Check the longest side of the image and resize if necessary
|
||||||
|
int maxDimension = Math.Max(image.Width, image.Height);
|
||||||
|
if (maxDimension > 1200)
|
||||||
|
{
|
||||||
|
double scaleFactor = 1200.0 / maxDimension;
|
||||||
|
int newWidth = (int)(image.Width * scaleFactor);
|
||||||
|
int newHeight = (int)(image.Height * scaleFactor);
|
||||||
|
image.Mutate(x => x.Resize(newWidth, newHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the image as WebP with a quality level of 85 (for lossy compression)
|
||||||
|
var encoder = new WebpEncoder
|
||||||
|
{
|
||||||
|
Quality = 90,
|
||||||
|
FileFormat = WebpFileFormatType.Lossy
|
||||||
|
};
|
||||||
|
|
||||||
|
image.Save(targetFilePath, encoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@ namespace Comic_Compressor
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("请输入目标存储位置:");
|
Console.WriteLine("请选择保存位置:");
|
||||||
string? targetStoragePath = GetFolderPath();
|
string? targetStoragePath = GetFolderPath();
|
||||||
if (string.IsNullOrEmpty(targetStoragePath))
|
if (string.IsNullOrEmpty(targetStoragePath))
|
||||||
{
|
{
|
||||||
@ -29,7 +29,7 @@ namespace Comic_Compressor
|
|||||||
int threadCount = int.Parse(Console.ReadLine() ?? "2");
|
int threadCount = int.Parse(Console.ReadLine() ?? "2");
|
||||||
Console.WriteLine($"处理线程数设定:{threadCount}");
|
Console.WriteLine($"处理线程数设定:{threadCount}");
|
||||||
|
|
||||||
Console.WriteLine("请选择压缩模式:0 - 压缩成webp,1 - 压缩成avif");
|
Console.WriteLine("目标格式:0 - webp, 1 - avif, 2 - JXL(JPEG-XL), 3 - JPG, 4 - PNG, 5 - 保留原格式(best effort)");
|
||||||
string? modeInput = Console.ReadLine();
|
string? modeInput = Console.ReadLine();
|
||||||
if (modeInput == null)
|
if (modeInput == null)
|
||||||
{
|
{
|
||||||
@ -47,12 +47,24 @@ namespace Comic_Compressor
|
|||||||
AvifCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount);
|
AvifCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount);
|
||||||
GetCompressorResult(sourceImagePath, targetStoragePath);
|
GetCompressorResult(sourceImagePath, targetStoragePath);
|
||||||
break;
|
break;
|
||||||
|
case "2":
|
||||||
|
JxlCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount);
|
||||||
|
GetCompressorResult(sourceImagePath, targetStoragePath);
|
||||||
|
break;
|
||||||
|
case "3":
|
||||||
|
case "4":
|
||||||
|
LegacyFormatCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount,int.Parse(modeInput));
|
||||||
|
GetCompressorResult(sourceImagePath, targetStoragePath);
|
||||||
|
break;
|
||||||
|
case "5":
|
||||||
|
throw new NotImplementedException();
|
||||||
default:
|
default:
|
||||||
Console.WriteLine("不支持的模式");
|
Console.WriteLine("不支持的格式");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static string? GetFolderPath()
|
private static string? GetFolderPath()
|
||||||
{
|
{
|
||||||
using var dialog = new FolderBrowserDialog();
|
using var dialog = new FolderBrowserDialog();
|
||||||
@ -74,10 +86,8 @@ namespace Comic_Compressor
|
|||||||
{
|
{
|
||||||
long size = 0;
|
long size = 0;
|
||||||
|
|
||||||
// 遍历目录中的所有文件
|
|
||||||
foreach (string file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories))
|
foreach (string file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories))
|
||||||
{
|
{
|
||||||
// 获取文件的大小并累加到总大小中
|
|
||||||
FileInfo fileInfo = new(file);
|
FileInfo fileInfo = new(file);
|
||||||
size += fileInfo.Length;
|
size += fileInfo.Length;
|
||||||
}
|
}
|
||||||
@ -85,15 +95,30 @@ namespace Comic_Compressor
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetHumanReadableSize(long size)
|
||||||
|
{
|
||||||
|
string[] sizes = { "B", "KB", "MB", "GB", "TB" };
|
||||||
|
double len = size;
|
||||||
|
int order = 0;
|
||||||
|
while (len >= 1024 && order < sizes.Length - 1)
|
||||||
|
{
|
||||||
|
order++;
|
||||||
|
len = len / 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $"{len:0.##} {sizes[order]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void GetCompressorResult(string source, string target)
|
private static void GetCompressorResult(string source, string target)
|
||||||
{
|
{
|
||||||
long sourceSize = GetDirectorySize(source);
|
long sourceSize = GetDirectorySize(source);
|
||||||
long targetSize = GetDirectorySize(target);
|
long targetSize = GetDirectorySize(target);
|
||||||
double reduced = (sourceSize - targetSize) * 1.0 / sourceSize;
|
double reduced = (sourceSize - targetSize) * 1.0 / sourceSize;
|
||||||
|
|
||||||
Console.WriteLine($"源目录大小:{sourceSize} 字节");
|
Console.WriteLine($"压缩前大小:{GetHumanReadableSize(sourceSize)}");
|
||||||
Console.WriteLine($"目标目录大小:{targetSize} 字节");
|
Console.WriteLine($"压缩后大小:{GetHumanReadableSize(targetSize)}");
|
||||||
Console.WriteLine($"已减少:{reduced:P}的体积");
|
Console.WriteLine($"体积已减少{reduced:P}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user