Skip to content

Commit 3f0a1da

Browse files
committed
完成对接命令行
1 parent 7fd5ea4 commit 3f0a1da

10 files changed

Lines changed: 321 additions & 38 deletions

File tree

src/MediaConverters/MediaConverters.Tool/Contexts/ErrorCode.cs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
6-
7-
namespace DotNetCampus.MediaConverter.Contexts;
1+
namespace DotNetCampus.MediaConverters.Contexts;
82

93
internal readonly record struct ErrorCode
104
{
@@ -18,6 +12,14 @@ internal readonly record struct ErrorCode
1812
/// </summary>
1913
public static readonly ErrorCode UnknownError = new(-1, "Unknown error");
2014

15+
public static readonly ErrorCode UnknownImageFormat = new(1001, "Unknown image format");
16+
17+
public static readonly ErrorCode InvalidImageContent = new(1002, "Invalid image content");
18+
19+
public static readonly ErrorCode ImageFileNotFound = new(1003, "Image file not found");
20+
21+
public static readonly ErrorCode NotSupported = new(1004, "Not supported operation");
22+
2123
/// <summary>
2224
/// 错误代码
2325
/// </summary>
@@ -38,4 +40,28 @@ public ErrorCode(int code, string message)
3840
}
3941

4042
private static List<ErrorCode>? CodeList { get; set; }
41-
}
43+
44+
public static bool TryGetErrorCode(int code, out ErrorCode errorCode)
45+
{
46+
if (CodeList is null)
47+
{
48+
errorCode = UnknownError;
49+
return false;
50+
}
51+
52+
var index = CodeList.FindIndex(t => t.Code == code);
53+
if (index < 0)
54+
{
55+
errorCode = UnknownError;
56+
return false;
57+
}
58+
59+
errorCode = CodeList[index];
60+
return true;
61+
}
62+
63+
public static implicit operator int(ErrorCode errorCode)
64+
{
65+
return errorCode.Code;
66+
}
67+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using SixLabors.ImageSharp;
2+
using SixLabors.ImageSharp.PixelFormats;
3+
4+
using System.Text.Json.Serialization;
5+
6+
namespace DotNetCampus.MediaConverters.Contexts;
7+
8+
[JsonDerivedType(typeof(ReplaceColorTask))]
9+
public interface IImageConvertTask
10+
{
11+
void Run(Image<Rgba32> image);
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace DotNetCampus.MediaConverters.Contexts;
2+
3+
public class ImageConvertContext
4+
{
5+
public int? MaxImageWidth { get; init; }
6+
public int? MaxImageHeight { get; init; }
7+
8+
public bool? UseAreaSizeLimit { get; init; }
9+
10+
public List<IImageConvertTask>? ImageConvertTaskList { get; init; }
11+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using DotNetCampus.Cli.Compiler;
2+
3+
namespace DotNetCampus.MediaConverters.Contexts;
4+
5+
public class Options
6+
{
7+
[Option]
8+
public required string WorkingFolder { get; init; }
9+
10+
[Option]
11+
public required string OutputFile { get; init; }
12+
13+
[Option]
14+
public required string InputFile { get; init; }
15+
16+
[Option]
17+
public required string ConvertConfigurationFile { get; init; }
18+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
namespace DotNetCampus.MediaConverters.Contexts;
2+
3+
public record ReplaceColorInfo(string OldColor, string NewColor);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using DotNetCampus.MediaConverters.Imaging.Effects;
2+
using DotNetCampus.MediaConverters.Imaging.Effects.Colors;
3+
using DotNetCampus.MediaConverters.Utils;
4+
using SixLabors.ImageSharp;
5+
using SixLabors.ImageSharp.PixelFormats;
6+
7+
namespace DotNetCampus.MediaConverters.Contexts;
8+
9+
public class ReplaceColorTask : IImageConvertTask
10+
{
11+
public List<ReplaceColorInfo>? ReplaceColorInfoList { get; init; }
12+
13+
public void Run(Image<Rgba32> image)
14+
{
15+
if (ReplaceColorInfoList is null || ReplaceColorInfoList.Count ==0)
16+
{
17+
return;
18+
}
19+
20+
var dictionary = new Dictionary<ColorMetadata, ColorMetadata>(ReplaceColorInfoList.Count);
21+
foreach (var replaceColorInfo in ReplaceColorInfoList)
22+
{
23+
var (oldColor, newColor) = replaceColorInfo.ToRgba32Pair();
24+
var oldMetadata = new ColorMetadata(oldColor);
25+
var newMetadata = new ColorMetadata(newColor);
26+
dictionary[oldMetadata] = newMetadata;
27+
}
28+
29+
image.ReplaceColor(dictionary);
30+
}
31+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace DotNetCampus.MediaConverters.Contexts;
4+
5+
[JsonSourceGenerationOptions(WriteIndented = true)]
6+
[JsonSerializable(typeof(ReplaceColorInfo))]
7+
[JsonSerializable(typeof(ImageConvertContext))]
8+
[JsonSerializable(typeof(IImageConvertTask))]
9+
internal partial class SourceGenerationContext : JsonSerializerContext
10+
{
11+
}

src/MediaConverters/MediaConverters.Tool/MediaConverters.Tool.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
<Nullable>enable</Nullable>
88
<RootNamespace>DotNetCampus.MediaConverters</RootNamespace>
99
<!-- 故意去掉 s 方便生成名为 DotNetCampus.MediaConverter.exe 的文件 -->
10-
<RootNamespace>DotNetCampus.MediaConverter</RootNamespace>
10+
<AssemblyName>DotNetCampus.MediaConverter</AssemblyName>
1111
</PropertyGroup>
1212

13+
<ItemGroup>
14+
<PackageReference Include="DotNetCampus.CommandLine" Version="4.0.0-alpha04" />
15+
</ItemGroup>
16+
1317
<ItemGroup>
1418
<ProjectReference Include="..\MediaConverters.Lib\MediaConverters.Lib.csproj" />
1519
</ItemGroup>
Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,80 @@
11
// See https://aka.ms/new-console-template for more information
22

3+
using System.Diagnostics;
4+
using System.Text.Json;
5+
6+
using DotNetCampus.MediaConverters.Contexts;
7+
using DotNetCampus.MediaConverters.Imaging.Optimizations;
8+
39
using SixLabors.ImageSharp;
4-
using SixLabors.ImageSharp.Formats;
5-
using SixLabors.ImageSharp.Formats.Bmp;
6-
using SixLabors.ImageSharp.Formats.Tiff;
7-
using SixLabors.ImageSharp.Formats.Webp;
810
using SixLabors.ImageSharp.PixelFormats;
9-
using SixLabors.ImageSharp.Processing;
11+
using SourceGenerationContext = DotNetCampus.MediaConverters.Contexts.SourceGenerationContext;
1012

11-
using System.Text;
13+
namespace DotNetCampus.MediaConverters;
1214

13-
ImageDecoder d = WebpDecoder.Instance;
15+
public class Program
16+
{
17+
public static async Task<int> Main(string[] args)
18+
{
19+
var options = DotNetCampus.Cli.CommandLine.Parse(args).As<Options>();
1420

15-
var maxPixelCount = 100_00_00;
21+
var jsonText = await File.ReadAllTextAsync(options.ConvertConfigurationFile);
22+
var imageConvertContext = JsonSerializer.Deserialize<ImageConvertContext>(jsonText, SourceGenerationContext.Default.Options);
1623

17-
var w = 1500;
18-
var h = 1300;
24+
if (imageConvertContext is null)
25+
{
26+
Console.Error.WriteLine("无法解析转换配置文件,请检查配置文件内容是否正确。");
27+
return ErrorCode.UnknownError;
28+
}
1929

20-
var s = w / (double) h;
30+
var inputFile = new FileInfo(options.InputFile);
2131

22-
var pw = (int) Math.Sqrt(maxPixelCount * w / (double) h);
23-
var ph = (int) Math.Sqrt(maxPixelCount * h / (double) w);
32+
var workingFolder = Directory.CreateDirectory(options.WorkingFolder);
2433

25-
var s1 = pw / (double) ph;
34+
var imageFileOptimizationResult = await ImageFileOptimization.OptimizeImageFileAsync(inputFile, workingFolder, imageConvertContext.MaxImageWidth, imageConvertContext.MaxImageHeight, imageConvertContext.UseAreaSizeLimit ?? true);
2635

36+
if (!imageFileOptimizationResult.IsSuccess)
37+
{
38+
Console.Error.WriteLine(imageFileOptimizationResult);
2739

40+
switch (imageFileOptimizationResult.FailureReason)
41+
{
42+
case ImageFileOptimizationFailureReason.Ok:
43+
Debug.Fail("返回成功时,不可能状态是失败");
44+
break;
45+
case ImageFileOptimizationFailureReason.UnknownImageFormat:
46+
return ErrorCode.UnknownImageFormat;
47+
break;
48+
case ImageFileOptimizationFailureReason.InvalidImageContent:
49+
return ErrorCode.InvalidImageContent;
50+
break;
51+
case ImageFileOptimizationFailureReason.FileNotFound:
52+
return ErrorCode.ImageFileNotFound;
53+
break;
54+
case ImageFileOptimizationFailureReason.NotSupported:
55+
return ErrorCode.NotSupported;
56+
break;
57+
default:
58+
throw new ArgumentOutOfRangeException();
59+
}
2860

29-
var tiffFile = @"E:\Download\file_example_TIFF_1MB.tiff";
30-
var file = @"E:\Download\file_example_favicon.ico";
31-
var buffer = File.ReadAllBytes(file);
61+
return ErrorCode.UnknownError;
62+
}
3263

33-
try
34-
{
35-
var image = Image.Load<Rgba32>(buffer);
36-
image.Mutate(context => context.Resize(new Size(100, 100), compand: true));
37-
Console.WriteLine(image.Width);
38-
image.SaveAsPng("1.png");
64+
FileInfo optimizedImageFile = imageFileOptimizationResult.OptimizedImageFile;
3965

40-
41-
}
42-
catch (ImageFormatException e)
43-
{
44-
}
66+
if (imageConvertContext.ImageConvertTaskList is { } list)
67+
{
68+
using var image = await Image.LoadAsync<Rgba32>(optimizedImageFile.FullName);
69+
70+
foreach (var imageConvertTask in list)
71+
{
72+
imageConvertTask.Run(image);
73+
}
74+
}
4575

46-
Console.WriteLine("Hello, World!");
76+
optimizedImageFile.CopyTo(options.OutputFile, overwrite: true);
77+
78+
return 0;
79+
}
80+
}

0 commit comments

Comments
 (0)