WeddingPlatform.Web 1.0.0.0
지도, 갤러리, 방명록, 계좌 안내와 배경음악을 링크 하나에 담는 무료 모바일 청첩장 서비스입니다.
로딩중...
검색중...
일치하는것 없음
SystemDrawingImageOptimizationService.cs
이 파일의 문서화 페이지로 가기
1using System.Drawing;
2using System.Drawing.Drawing2D;
3using System.Drawing.Imaging;
4using System.IO;
6
8
18{
43 public bool CanEncode(string outputFormat)
44 {
45 var format = NormalizeFormat(outputFormat);
46 return format is "jpg" or "jpeg" or "png";
47 }
48
97 public Task<ImageOptimizationResult> OptimizeAsync(string sourcePath, string destinationPath, EffectiveMediaPolicy policy, CancellationToken ct = default)
98 {
99 ct.ThrowIfCancellationRequested();
100
101 var format = NormalizeFormat(Path.GetExtension(destinationPath));
102 if (string.IsNullOrWhiteSpace(format))
103 {
104 format = NormalizeFormat(policy.ImageOutputFormat);
105 }
106
107 if (!CanEncode(format))
108 {
109 return Task.FromResult(new ImageOptimizationResult
110 {
111 Skipped = true,
112 Message = $"{format} 인코더를 사용할 수 없어 원본 표시 파일을 유지했습니다."
113 });
114 }
115
116 using var source = Image.FromFile(sourcePath);
117 using var output = CreateResizedBitmap(source, policy.ImageMaxLongSidePx);
118
119 Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)!);
120 if (format is "jpg" or "jpeg")
121 {
122 SaveJpeg(output, destinationPath, policy.ImageQuality);
123 }
124 else
125 {
126 output.Save(destinationPath, ImageFormat.Png);
127 }
128
129 return Task.FromResult(new ImageOptimizationResult
130 {
131 Succeeded = File.Exists(destinationPath) && new FileInfo(destinationPath).Length > 0,
132 FileName = Path.GetFileName(destinationPath),
133 Message = "이미지 최적화 완료"
134 });
135 }
136
169 private static Bitmap CreateResizedBitmap(Image source, int maxLongSide)
170 {
171 var boundedLongSide = maxLongSide <= 0 ? 1920 : maxLongSide;
172 var scale = Math.Min(1d, boundedLongSide / (double)Math.Max(source.Width, source.Height));
173 var width = Math.Max(1, (int)Math.Round(source.Width * scale));
174 var height = Math.Max(1, (int)Math.Round(source.Height * scale));
175
176 var bitmap = new Bitmap(width, height);
177 bitmap.SetResolution(source.HorizontalResolution, source.VerticalResolution);
178 using var graphics = Graphics.FromImage(bitmap);
179 graphics.CompositingQuality = CompositingQuality.HighQuality;
180 graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
181 graphics.SmoothingMode = SmoothingMode.HighQuality;
182 graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
183 graphics.Clear(Color.White);
184 graphics.DrawImage(source, 0, 0, width, height);
185 return bitmap;
186 }
187
220 private static void SaveJpeg(Image image, string path, int quality)
221 {
222 var codec = ImageCodecInfo.GetImageEncoders()
223 .FirstOrDefault(x => x.FormatID == ImageFormat.Jpeg.Guid);
224 if (codec is null)
225 {
226 image.Save(path, ImageFormat.Jpeg);
227 return;
228 }
229
230 using var parameters = new EncoderParameters(1);
231 parameters.Param[0] = new EncoderParameter(Encoder.Quality, Math.Clamp(quality, 1, 100));
232 image.Save(path, codec, parameters);
233 }
234
259 private static string NormalizeFormat(string? outputFormat)
260 {
261 var normalized = outputFormat?.Trim().TrimStart('.').ToLowerInvariant();
262 return string.IsNullOrWhiteSpace(normalized) ? "" : normalized;
263 }
264}
Task< ImageOptimizationResult > OptimizeAsync(string sourcePath, string destinationPath, EffectiveMediaPolicy policy, CancellationToken ct=default)