添加项目文件。
This commit is contained in:
parent
80384cdd20
commit
3860b1bd54
31
Comic_Compressor.sln
Normal file
31
Comic_Compressor.sln
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.11.35219.272
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Comic_Compressor", "Comic_Compressor\Comic_Compressor.csproj", "{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{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|x64.ActiveCfg = Debug|x64
|
||||||
|
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{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|x64.ActiveCfg = Release|x64
|
||||||
|
{B6B0E3D8-DE3D-4A7D-AAE5-34953ABFEA2A}.Release|x64.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {FA1DD3CC-0702-404F-9D7F-40EB2736F8AD}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
17
Comic_Compressor/AvifCompressor.cs
Normal file
17
Comic_Compressor/AvifCompressor.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Comic_Compressor
|
||||||
|
{
|
||||||
|
internal class AvifCompressor
|
||||||
|
{
|
||||||
|
internal static void CompressImages(string sourceImagePath, string targetStoragePath)
|
||||||
|
{
|
||||||
|
//尚未实现
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
Comic_Compressor/Comic_Compressor.csproj
Normal file
17
Comic_Compressor/Comic_Compressor.csproj
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
|
<UseWindowsForms>True</UseWindowsForms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="LibHeifSharp" Version="3.2.0" />
|
||||||
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
67
Comic_Compressor/Program.cs
Normal file
67
Comic_Compressor/Program.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
namespace Comic_Compressor
|
||||||
|
{
|
||||||
|
internal class Program
|
||||||
|
{
|
||||||
|
[STAThread]
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
Console.OutputEncoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
Console.WriteLine("请选择源图像所在位置:");
|
||||||
|
string? sourceImagePath = GetFolderPath();
|
||||||
|
if (string.IsNullOrEmpty(sourceImagePath))
|
||||||
|
{
|
||||||
|
Console.WriteLine("未选择文件夹,程序将退出。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("请输入目标存储位置:");
|
||||||
|
string? targetStoragePath = GetFolderPath();
|
||||||
|
if (string.IsNullOrEmpty(targetStoragePath))
|
||||||
|
{
|
||||||
|
Console.WriteLine("未选择文件夹,程序将退出。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("请选择压缩模式:0 - 压缩成webp,1 - 压缩成avif");
|
||||||
|
string? modeInput = Console.ReadLine();
|
||||||
|
if (modeInput == null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("无效输入");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (modeInput)
|
||||||
|
{
|
||||||
|
case "0":
|
||||||
|
WebpCompressor.CompressImages(sourceImagePath, targetStoragePath);
|
||||||
|
break;
|
||||||
|
case "1":
|
||||||
|
AvifCompressor.CompressImages(sourceImagePath, targetStoragePath);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Console.WriteLine("不支持的模式");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? GetFolderPath()
|
||||||
|
{
|
||||||
|
using var dialog = new FolderBrowserDialog();
|
||||||
|
dialog.ShowNewFolderButton = false;
|
||||||
|
|
||||||
|
DialogResult result = dialog.ShowDialog();
|
||||||
|
|
||||||
|
if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(dialog.SelectedPath))
|
||||||
|
{
|
||||||
|
return dialog.SelectedPath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
82
Comic_Compressor/WebpCompressor.cs
Normal file
82
Comic_Compressor/WebpCompressor.cs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.Formats.Webp;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
|
||||||
|
namespace Comic_Compressor
|
||||||
|
{
|
||||||
|
internal class WebpCompressor
|
||||||
|
{
|
||||||
|
internal static void CompressImages(string sourceImagePath, string targetStoragePath)
|
||||||
|
{
|
||||||
|
// Step 1: Get all subdirectories and store them in a list
|
||||||
|
List<string> subdirectories = new(Directory.GetDirectories(sourceImagePath, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
// Step 2: Iterate through each subdirectory in order
|
||||||
|
foreach (string subdirectory in subdirectories)
|
||||||
|
{
|
||||||
|
// Step 3: Process each directory
|
||||||
|
ProcessDirectory(subdirectory, sourceImagePath, targetStoragePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ProcessDirectory(string subdirectory, string sourceImagePath, string targetStoragePath)
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Iterate through each image file
|
||||||
|
foreach (string imageFile in imageFiles)
|
||||||
|
{
|
||||||
|
// Set the target file path with the .webp extension
|
||||||
|
string targetFilePath = Path.Combine(targetSubdirectory, Path.GetFileNameWithoutExtension(imageFile) + ".webp");
|
||||||
|
CompressImage(imageFile, targetFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"{Path.GetFileName(subdirectory)} processed successfully.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string[] GetImageFiles(string directoryPath)
|
||||||
|
{
|
||||||
|
// Get all image files supported by ImageSharp
|
||||||
|
string[] supportedExtensions = ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.tiff"];
|
||||||
|
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 70 (for lossy compression)
|
||||||
|
var encoder = new WebpEncoder
|
||||||
|
{
|
||||||
|
Quality = 70,
|
||||||
|
FileFormat = WebpFileFormatType.Lossy
|
||||||
|
};
|
||||||
|
|
||||||
|
image.Save(targetFilePath, encoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user