Compare commits
No commits in common. "master" and "0.0.3b1" have entirely different histories.
@ -3,30 +3,24 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.11.35219.272
|
VisualStudioVersion = 17.11.35219.272
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Comic_Compressor", "Comic_Compressor\Comic_Compressor.csproj", "{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Comic_Compressor", "Comic_Compressor\Comic_Compressor.csproj", "{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
Debug|x86 = Debug|x86
|
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
Release|x86 = Release|x86
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Debug|x64.ActiveCfg = Debug|x64
|
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Debug|x64.Build.0 = Debug|x64
|
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Debug|x64.Build.0 = Debug|x64
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Debug|x86.ActiveCfg = Debug|x86
|
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Debug|x86.Build.0 = Debug|x86
|
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Release|x64.ActiveCfg = Release|x64
|
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Release|x64.ActiveCfg = Release|x64
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Release|x64.Build.0 = Release|x64
|
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Release|x64.Build.0 = Release|x64
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Release|x86.ActiveCfg = Release|x86
|
|
||||||
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Release|x86.Build.0 = Release|x86
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -5,11 +5,12 @@ namespace Comic_Compressor
|
|||||||
{
|
{
|
||||||
internal class AvifCompressor : Utils
|
internal class AvifCompressor : Utils
|
||||||
{
|
{
|
||||||
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount, bool usePresetQuality, int Quality)
|
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount)
|
||||||
{
|
{
|
||||||
|
//config
|
||||||
MagickFormat targetFormat = MagickFormat.Avif;
|
MagickFormat targetFormat = MagickFormat.Avif;
|
||||||
string targetExtension = ".avif";
|
string targetExtension = ".avif";
|
||||||
int targetQuality = usePresetQuality ? 80 : Quality;
|
int targetQuality = 80;
|
||||||
|
|
||||||
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<UseWindowsForms>True</UseWindowsForms>
|
<UseWindowsForms>True</UseWindowsForms>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -5,11 +5,12 @@ namespace Comic_Compressor
|
|||||||
{
|
{
|
||||||
internal class JxlCompressor : Utils
|
internal class JxlCompressor : Utils
|
||||||
{
|
{
|
||||||
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount, bool usePresetQuality, int Quality)
|
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount)
|
||||||
{
|
{
|
||||||
|
//config
|
||||||
MagickFormat targetFormat = MagickFormat.Jxl;
|
MagickFormat targetFormat = MagickFormat.Jxl;
|
||||||
string targetExtension = ".jxl";
|
string targetExtension = ".jxl";
|
||||||
int targetQuality = usePresetQuality ? 90 : Quality;
|
int targetQuality = 90;
|
||||||
|
|
||||||
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
@ -5,25 +5,14 @@ namespace Comic_Compressor
|
|||||||
//Process images in legacy format(JPG,PNG)
|
//Process images in legacy format(JPG,PNG)
|
||||||
internal class LegacyFormatCompressor : Utils
|
internal class LegacyFormatCompressor : Utils
|
||||||
{
|
{
|
||||||
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount, bool usePresetQuality, int Quality, int format)
|
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount, int format)
|
||||||
{
|
{
|
||||||
MagickFormat targetFormat = format switch
|
//check format
|
||||||
{
|
throw new NotImplementedException();
|
||||||
3 => MagickFormat.Jpeg,
|
//config
|
||||||
4 => MagickFormat.Png,
|
MagickFormat targetFormat = MagickFormat.Jxl;
|
||||||
5 => MagickFormat.Bmp,
|
string targetExtension = ".jxl";
|
||||||
_ => throw new Exception(),
|
int targetQuality = 90;
|
||||||
};
|
|
||||||
|
|
||||||
string targetExtension = format switch
|
|
||||||
{
|
|
||||||
3 => ".jpg",
|
|
||||||
4 => ".png",
|
|
||||||
5 => ".bmp",
|
|
||||||
_ => throw new Exception(),
|
|
||||||
};
|
|
||||||
|
|
||||||
int targetQuality = usePresetQuality ? 90 : Quality;
|
|
||||||
|
|
||||||
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
using ShellProgressBar;
|
using ImageMagick;
|
||||||
|
using ShellProgressBar;
|
||||||
namespace Comic_Compressor
|
namespace Comic_Compressor
|
||||||
{
|
{
|
||||||
internal class MixProcessor : Utils
|
internal class MixProcessor : Utils
|
||||||
{
|
{
|
||||||
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount, bool usePresetQuality, int Quality)
|
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount, int format)
|
||||||
{
|
{
|
||||||
int targetQuality = usePresetQuality ? 90 : Quality;
|
//detect mu-config
|
||||||
|
throw new NotImplementedException();
|
||||||
|
//config
|
||||||
|
MagickFormat targetFormat = MagickFormat.Jxl;
|
||||||
|
string targetExtension = ".jxl";
|
||||||
|
int targetQuality = 90;
|
||||||
|
|
||||||
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
@ -23,7 +29,7 @@ namespace Comic_Compressor
|
|||||||
|
|
||||||
foreach (string subdirectory in subdirectories)
|
foreach (string subdirectory in subdirectories)
|
||||||
{
|
{
|
||||||
ProcessDirectory(subdirectory, sourceImagePath, targetStoragePath, progressBar, threadCount, targetQuality);
|
ProcessDirectory(subdirectory, sourceImagePath, targetStoragePath, progressBar, threadCount, targetExtension, targetFormat, targetQuality);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("All directories processed successfully.");
|
Console.WriteLine("All directories processed successfully.");
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Text;
|
using ImageMagick;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
namespace Comic_Compressor
|
namespace Comic_Compressor
|
||||||
{
|
{
|
||||||
internal class Program
|
internal class Program
|
||||||
@ -27,13 +29,9 @@ namespace Comic_Compressor
|
|||||||
|
|
||||||
Console.WriteLine("处理线程数:");
|
Console.WriteLine("处理线程数:");
|
||||||
int threadCount = int.Parse(Console.ReadLine() ?? "2");
|
int threadCount = int.Parse(Console.ReadLine() ?? "2");
|
||||||
if (threadCount < 1)
|
Console.WriteLine($"处理线程数设定:{threadCount}");
|
||||||
{
|
|
||||||
Console.WriteLine("无效线程数");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine("目标格式:0 - webp, 1 - avif, 2 - JXL(JPEG-XL), 3 - JPG, 4 - PNG, 5 - BMP, 6 - 保留原格式");
|
Console.WriteLine("目标格式:0 - webp, 1 - avif, 2 - JXL(JPEG-XL), 3 - JPG, 4 - PNG, 5 - BMP, 6 - 保留原格式(best effort)");
|
||||||
string? modeInput = Console.ReadLine();
|
string? modeInput = Console.ReadLine();
|
||||||
if (modeInput == null)
|
if (modeInput == null)
|
||||||
{
|
{
|
||||||
@ -41,51 +39,32 @@ namespace Comic_Compressor
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("使用预设质量(默认使用)?(y/n)");
|
|
||||||
string? input = Console.ReadLine()?.Trim().ToLower();
|
|
||||||
bool usePresetQuality = input == null || input == "" || input == "y" || input == "yes";
|
|
||||||
int targetQuality = -1;
|
|
||||||
if (!usePresetQuality)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Quality (0-100 INT):");
|
|
||||||
string? targetQualityStr = Console.ReadLine();
|
|
||||||
if (targetQualityStr == null)
|
|
||||||
{
|
|
||||||
Console.WriteLine("无效输入");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
targetQuality = int.Parse(targetQualityStr);
|
|
||||||
if (targetQuality < 0 || targetQuality > 100)
|
|
||||||
{
|
|
||||||
Console.WriteLine("invalid image quality");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (modeInput)
|
switch (modeInput)
|
||||||
{
|
{
|
||||||
case "0":
|
case "0":
|
||||||
WebpCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount, usePresetQuality, targetQuality);
|
WebpCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount);
|
||||||
|
Utils.GetCompressorResult(sourceImagePath, targetStoragePath);
|
||||||
break;
|
break;
|
||||||
case "1":
|
case "1":
|
||||||
AvifCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount, usePresetQuality, targetQuality);
|
AvifCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount);
|
||||||
|
Utils.GetCompressorResult(sourceImagePath, targetStoragePath);
|
||||||
break;
|
break;
|
||||||
case "2":
|
case "2":
|
||||||
JxlCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount, usePresetQuality, targetQuality);
|
JxlCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount);
|
||||||
|
Utils.GetCompressorResult(sourceImagePath, targetStoragePath);
|
||||||
break;
|
break;
|
||||||
case "3":
|
case "3":
|
||||||
case "4":
|
case "4":
|
||||||
case "5":
|
case "5":
|
||||||
LegacyFormatCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount, usePresetQuality, targetQuality, int.Parse(modeInput));
|
LegacyFormatCompressor.CompressImages(sourceImagePath, targetStoragePath, threadCount,int.Parse(modeInput));
|
||||||
|
Utils.GetCompressorResult(sourceImagePath, targetStoragePath);
|
||||||
break;
|
break;
|
||||||
case "6":
|
case "6":
|
||||||
MixProcessor.CompressImages(sourceImagePath, targetStoragePath, threadCount, usePresetQuality, targetQuality);
|
throw new NotImplementedException();
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
Console.WriteLine("不支持的格式");
|
Console.WriteLine("不支持的格式");
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
Utils.GetCompressorResult(sourceImagePath, targetStoragePath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ namespace Comic_Compressor
|
|||||||
// Get all image files in a directory with supported extensions
|
// Get all image files in a directory with supported extensions
|
||||||
public static string[] GetImageFiles(string directoryPath)
|
public static string[] GetImageFiles(string directoryPath)
|
||||||
{
|
{
|
||||||
string[] supportedExtensions = ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.tiff", "*.tif", "*.jxl", "*.avif", "*.webp"];
|
string[] supportedExtensions = ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.tiff", "*.jxl", "*.avif", "*.webp"];
|
||||||
ConcurrentBag<string> allFiles = [];
|
ConcurrentBag<string> allFiles = [];
|
||||||
|
|
||||||
foreach (string extension in supportedExtensions)
|
foreach (string extension in supportedExtensions)
|
||||||
@ -76,56 +76,6 @@ namespace Comic_Compressor
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//Process all image files in a directory, save as origin format
|
|
||||||
public static void ProcessDirectory(string subdirectory, string sourceImagePath, string targetStoragePath, ShellProgressBar.ProgressBar progressBar, int threadCount, int quality)
|
|
||||||
{
|
|
||||||
string relativePath = Path.GetRelativePath(sourceImagePath, subdirectory);
|
|
||||||
|
|
||||||
string targetSubdirectory = Path.Combine(targetStoragePath, relativePath);
|
|
||||||
Directory.CreateDirectory(targetSubdirectory);
|
|
||||||
|
|
||||||
string[] imageFiles = GetImageFiles(subdirectory);
|
|
||||||
|
|
||||||
ParallelOptions options = new()
|
|
||||||
{
|
|
||||||
MaxDegreeOfParallelism = threadCount // Adjust this value to set the number of concurrent threads
|
|
||||||
};
|
|
||||||
|
|
||||||
Parallel.ForEach(imageFiles, options, imageFile =>
|
|
||||||
{
|
|
||||||
string targetFilePath = Path.Combine(targetSubdirectory, Path.GetFileName(imageFile));
|
|
||||||
//detect file format
|
|
||||||
//supportedExtensions = ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.tiff", "*.jxl", "*.avif", "*.webp"];
|
|
||||||
string extension = Path.GetExtension(targetFilePath).ToLower();
|
|
||||||
|
|
||||||
MagickFormat mFormat = extension switch
|
|
||||||
{
|
|
||||||
".jpg" or ".jpeg" => MagickFormat.Jpeg,
|
|
||||||
".png" => MagickFormat.Png,
|
|
||||||
".bmp" => MagickFormat.Bmp,
|
|
||||||
".gif" => MagickFormat.Gif,
|
|
||||||
".tiff" or ".tif" => MagickFormat.Tiff,
|
|
||||||
".jxl" => MagickFormat.Jxl,
|
|
||||||
".avif" => MagickFormat.Avif,
|
|
||||||
".webp" => MagickFormat.WebP,
|
|
||||||
_ => throw new Exception()//这个位置怎么还会有意外情况
|
|
||||||
};
|
|
||||||
if (!File.Exists(targetFilePath))
|
|
||||||
{
|
|
||||||
CompressImage(imageFile, targetFilePath, mFormat, quality);
|
|
||||||
|
|
||||||
lock (progressBar)
|
|
||||||
{
|
|
||||||
progressBar.Tick($"Processed {Path.GetFileName(imageFile)}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lock (progressBar) { progressBar.Tick($"Skipped {Path.GetFileName(imageFile)}"); }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the compression result
|
// Display the compression result
|
||||||
public static void GetCompressorResult(string source, string target)
|
public static void GetCompressorResult(string source, string target)
|
||||||
{
|
{
|
||||||
|
@ -5,11 +5,12 @@ namespace Comic_Compressor
|
|||||||
{
|
{
|
||||||
internal class WebpCompressor : Utils
|
internal class WebpCompressor : Utils
|
||||||
{
|
{
|
||||||
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount, bool usePresetQuality, int Quality)
|
internal static void CompressImages(string sourceImagePath, string targetStoragePath, int threadCount)
|
||||||
{
|
{
|
||||||
|
//config
|
||||||
MagickFormat targetFormat = MagickFormat.WebP;
|
MagickFormat targetFormat = MagickFormat.WebP;
|
||||||
string targetExtension = ".webp";
|
string targetExtension = ".webp";
|
||||||
int targetQuality = usePresetQuality ? 90 : Quality;
|
int targetQuality = 90;
|
||||||
|
|
||||||
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user