@@ -25,16 +25,19 @@ public static class ImageFileOptimization
2525 /// 其中,最大宽高是图片为 96.0 DPI 下的逻辑宽高。
2626 /// 在处理完后,将返回一张新的图片路径。
2727 /// </summary>
28- /// <param name="imageFile"></param>
29- /// <param name="maxImageWidth">限制图片的最大宽度。为空则表示不限制</param>
30- /// <param name="maxImageHeight">限制图片的最大高度。为空则表示不限制</param>
3128 /// <param name="copyNewFile">是否先行拷贝新的文件,再进行处理,避免图片占用。默认为 true。</param>
32- /// <param name="workingFolder "></param>
29+ /// <param name="context "></param>
3330 /// <param name="useAreaSizeLimit">当包含宽度高度限制时,采用面积限制。采用面积限制时,可能宽度或高度依然超过限制的最大宽度高度。采用面积限制时,可以保证最大像素数量小于限制数量的同时,让图片可以达到最大尺寸</param>
3431 /// <returns></returns>
35- public static async Task < ImageFileOptimizationResult > OptimizeImageFileAsync ( FileInfo imageFile ,
36- DirectoryInfo workingFolder , int ? maxImageWidth = null , int ? maxImageHeight = null , bool useAreaSizeLimit = true , bool copyNewFile = true )
32+ public static async Task < ImageFileOptimizationResult > OptimizeImageFileAsync ( ImageFileOptimizationContext context , bool useAreaSizeLimit = true , bool copyNewFile = true )
3733 {
34+ var imageFile = context . ImageFile ;
35+ var workingFolder = context . WorkingFolder ;
36+ var maxImageWidth = context . MaxImageWidth ;
37+ var maxImageHeight = context . MaxImageHeight ;
38+
39+ context . LogMessage ( $ "Start optimize image file. File='{ imageFile } '") ;
40+
3841 if ( ! File . Exists ( imageFile . FullName ) )
3942 {
4043 // 不能依靠 imageFile.Exists 属性,因为属性可能还没更新
@@ -47,54 +50,88 @@ public static async Task<ImageFileOptimizationResult> OptimizeImageFileAsync(Fil
4750
4851 Directory . CreateDirectory ( workingFolder . FullName ) ;
4952
50- var file = imageFile ;
5153 if ( copyNewFile )
5254 {
55+ var file = imageFile ;
5356 var newFilePath = Path . Join ( workingFolder . FullName , $ "Copy_{ Path . GetRandomFileName ( ) } _{ imageFile . Name } ") ;
5457 file . CopyTo ( newFilePath ) ;
58+ context . LogMessage ( $ "Copy new file to '{ newFilePath } '") ;
5559 file = new FileInfo ( newFilePath ) ;
60+
61+ context = context with
62+ {
63+ ImageFile = file
64+ } ;
5665 }
5766
5867 if ( IsExtension ( ".svg" ) )
5968 {
6069 // 如果是 svg 那就直接转换了,因为后续叠加特效等逻辑都不能支持 SVG 格式
61- var outputFilePath = ConvertSvgToPngFile ( file , workingFolder ) ;
62- if ( outputFilePath is null )
70+ try
71+ {
72+ var outputFilePath = ConvertSvgToPngFile ( context ) ;
73+ if ( outputFilePath is null )
74+ {
75+ return new ImageFileOptimizationResult ( )
76+ {
77+ OptimizedImageFile = null ,
78+ FailureReason = ImageFileOptimizationFailureReason . NotSupported
79+ } ;
80+ }
81+ else
82+ {
83+ context . LogMessage ( $ "Success ConvertSvgToPngFile. Update current image file to '{ outputFilePath . FullName } '") ;
84+ context = context with
85+ {
86+ ImageFile = outputFilePath
87+ } ;
88+ }
89+ }
90+ catch ( Exception e )
6391 {
92+ context . LogMessage ( $ "Convert SVG to PNG failed: { e } ") ;
93+
6494 return new ImageFileOptimizationResult ( )
6595 {
6696 OptimizedImageFile = null ,
97+ Exception = e ,
6798 FailureReason = ImageFileOptimizationFailureReason . NotSupported
6899 } ;
69100 }
70- else
71- {
72- file = outputFilePath ;
73- }
74101 }
75102 else if ( IsExtension ( ".wmf" ) ||
76103 IsExtension ( ".emf" ) )
77104 {
78- var result = EnhancedGraphicsMetafileOptimization . ConvertWmfOrEmfToPngFile ( file , workingFolder ) ;
105+ var result = EnhancedGraphicsMetafileOptimization . ConvertWmfOrEmfToPngFile ( context ) ;
79106 if ( result . OptimizedImageFile is not null )
80107 {
81- file = result . OptimizedImageFile ;
108+ context . LogMessage ( $ "Success ConvertWmfOrEmfToPngFile. Update current image file to '{ result . OptimizedImageFile } '") ;
109+ context = context with
110+ {
111+ ImageFile = result . OptimizedImageFile
112+ } ;
82113 }
83114 else
84115 {
85116 return result ;
86117 }
87118 }
88119
120+ context . LogMessage ( $ "Start optimize image with ImageSharp. ImageFile: '{ context . ImageFile . FullName } '") ;
121+
89122 Image < Rgba32 > image ;
90123 try
91124 {
92- await using var fileStream = new FileStream ( file . FullName , FileMode . Open , FileAccess . Read , FileShare . Read ) ;
125+ await using var fileStream = new FileStream ( context . ImageFile . FullName , FileMode . Open , FileAccess . Read ,
126+ FileShare . Read ) ;
93127
94128 image = await Image . LoadAsync < Rgba32 > ( fileStream ) ;
95129 }
96130 catch ( ImageFormatException e )
97131 {
132+ context . LogMessage (
133+ $ "Fail to load image with ImageSharp. ImageFile: '{ context . ImageFile . FullName } ' Exception: { e } ") ;
134+
98135 // 这里是明确的图片处理的错误,可以转换为输出信息。如果是其他错误,继续抛出
99136 ImageFileOptimizationFailureReason failureReason = default ;
100137
@@ -114,11 +151,19 @@ public static async Task<ImageFileOptimizationResult> OptimizeImageFileAsync(Fil
114151 FailureReason = failureReason
115152 } ;
116153 }
154+ catch ( Exception e )
155+ {
156+ context . LogMessage ( $ "Fail to load image with ImageSharp. ImageFile: '{ context . ImageFile . FullName } ' Exception: { e } ") ;
157+
158+ throw ;
159+ }
117160
118161 try
119162 {
120163 if ( image . Metadata . DecodedImageFormat is GifFormat )
121164 {
165+ context . LogMessage ( $ "Image format is Gif. NotSupported.") ;
166+
122167 image . Dispose ( ) ;
123168 return new ImageFileOptimizationResult ( )
124169 {
@@ -144,15 +189,17 @@ public static async Task<ImageFileOptimizationResult> OptimizeImageFileAsync(Fil
144189 FailureReason = ImageFileOptimizationFailureReason . Ok
145190 } ;
146191 }
147- catch
192+ catch ( Exception e )
148193 {
194+ context . LogMessage ( $ "Fail to optimize image with ImageSharp. ImageFile: '{ context . ImageFile . FullName } ' Exception: { e } ") ;
195+
149196 image . Dispose ( ) ;
150197 throw ;
151198 }
152199
153200 bool IsExtension ( string extension )
154201 {
155- return string . Equals ( file . Extension , extension , StringComparison . OrdinalIgnoreCase ) ;
202+ return string . Equals ( context . ImageFile . Extension , extension , StringComparison . OrdinalIgnoreCase ) ;
156203 }
157204 }
158205
@@ -267,16 +314,17 @@ public static void LimitImageSize(Image<Rgba32> image, int? maxImageWidth, int?
267314 /// <summary>
268315 /// 转换 svg 文件为 png 文件
269316 /// </summary>
270- /// <param name="imageFile"></param>
271- /// <param name="workingFolder"></param>
272317 /// <returns></returns>
273- public static FileInfo ? ConvertSvgToPngFile ( FileInfo imageFile ,
274- DirectoryInfo workingFolder )
318+ public static FileInfo ? ConvertSvgToPngFile ( ImageFileOptimizationContext context )
275319 {
320+ var imageFile = context . ImageFile ;
321+ var workingFolder = context . WorkingFolder ;
322+
276323 using var skSvg = new SKSvg ( ) ;
277324 using var skPicture = skSvg . Load ( imageFile . FullName ) ;
278325 var fileNameWithoutExtension = Path . GetFileNameWithoutExtension ( imageFile . Name ) ;
279- var outputFile = Path . Join ( workingFolder . FullName , $ "SVG_{ Path . GetRandomFileName ( ) } _{ fileNameWithoutExtension } .png") ;
326+ var outputFile = Path . Join ( workingFolder . FullName ,
327+ $ "SVG_{ Path . GetRandomFileName ( ) } _{ fileNameWithoutExtension } .png") ;
280328 var canSave = skSvg . Save ( outputFile , SKColors . Transparent ) ;
281329 if ( canSave && File . Exists ( outputFile ) )
282330 {
@@ -321,9 +369,11 @@ public static async Task<FileInfo> FixSvgInvalidCharacterAsync(FileInfo svgFile,
321369 return svgFile ;
322370 }
323371
324- public static FileInfo FixSvgInvalidCharacter ( FileInfo svgFile ,
325- DirectoryInfo workingFolder )
372+ public static FileInfo FixSvgInvalidCharacter ( ImageFileOptimizationContext context )
326373 {
374+ FileInfo svgFile = context . ImageFile ;
375+ DirectoryInfo workingFolder = context . WorkingFolder ;
376+
327377 using var fileStream = svgFile . OpenRead ( ) ;
328378 using var streamReader = new StreamReader ( fileStream ) ;
329379
0 commit comments