diff --git a/src/MagicScaler/Core/ProcessImageSettings.cs b/src/MagicScaler/Core/ProcessImageSettings.cs index 699ea87b..dfd37a10 100644 --- a/src/MagicScaler/Core/ProcessImageSettings.cs +++ b/src/MagicScaler/Core/ProcessImageSettings.cs @@ -252,7 +252,7 @@ public static ProcessImageSettings FromDictionary(IDictionary di FrameIndex = Math.Max(int.TryParse(dic.GetValueOrDefault("frame") ?? dic.GetValueOrDefault("page"), out int f) ? f : 0, 0), Width = Math.Max(int.TryParse(dic.GetValueOrDefault("width") ?? dic.GetValueOrDefault("w"), out int w) ? w : 0, 0), Height = Math.Max(int.TryParse(dic.GetValueOrDefault("height") ?? dic.GetValueOrDefault("h"), out int h) ? h : 0, 0), - JpegQuality = Math.Max(int.TryParse(dic.GetValueOrDefault("quality"), out int q) ? q : 0, 0) + JpegQuality = Math.Max(int.TryParse(dic.GetValueOrDefault("quality") ?? dic.GetValueOrDefault("q"), out int q) ? q : 0, 0) }; s.Sharpen = bool.TryParse(dic.GetValueOrDefault("sharpen"), out bool bs) ? bs : s.Sharpen; diff --git a/src/WebRSize/WebRSizeHandler.cs b/src/WebRSize/WebRSizeHandler.cs index f69401a0..c1376af6 100644 --- a/src/WebRSize/WebRSizeHandler.cs +++ b/src/WebRSize/WebRSizeHandler.cs @@ -3,6 +3,7 @@ using System.Web; using System.Web.Hosting; using System.Reflection; +using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using System.Collections.Concurrent; @@ -107,22 +108,29 @@ public override async Task ProcessRequestAsync(HttpContext ctx) if (tsource?.Task == task) { - ctx.Trace.Write("ProcessImage Begin"); + ctx.Trace.Write(nameof(WebRSize), $"{nameof(MagicImageProcessor.ProcessImage)} Begin"); await process(tsource, ctx.Request.Path, cachePath, s); - ctx.Trace.Write("ProcessImage End"); + ctx.Trace.Write(nameof(WebRSize), $"{nameof(MagicImageProcessor.ProcessImage)} End"); } - var res = await task; + var img = await task; + var res = ctx.Response; - if (!ctx.Response.IsClientConnected) + if (!res.IsClientConnected) return; - ctx.Response.BufferOutput = false; - ctx.Response.ContentType = MimeMapping.GetMimeMapping(Path.GetFileName(cachePath)); - ctx.Response.AddHeader("Content-Length", res.Count.ToString()); - ctx.Response.Cache.SetLastModifiedFromFileDependencies(); + try + { + res.BufferOutput = false; + res.ContentType = MimeMapping.GetMimeMapping(Path.GetFileName(cachePath)); + res.AddHeader("Content-Length", img.Count.ToString()); - await ctx.Response.OutputStream.WriteAsync(res.Array, res.Offset, res.Count); + await res.OutputStream.WriteAsync(img.Array, img.Offset, img.Count); + } + catch (HttpException ex) when (new StackTrace(ex).GetFrame(0)?.GetMethod().Name == "RaiseCommunicationError") + { + // no problem here. client just disconnected before transmission completed. + } } public override bool IsReusable => true; diff --git a/src/WebRSize/WebRSizeModule.cs b/src/WebRSize/WebRSizeModule.cs index 2b2365e0..60484512 100644 --- a/src/WebRSize/WebRSizeModule.cs +++ b/src/WebRSize/WebRSizeModule.cs @@ -37,6 +37,15 @@ private async Task mapRequest(object sender, EventArgs e) dic = folderConfig.DefaultSettings.ToDictionary().Coalesce(dic); var s = ProcessImageSettings.FromDictionary(dic); + + int rw = s.Width, rh = s.Height; + if (double.TryParse(dic.GetValueOrDefault("devicepixelratio") ?? dic.GetValueOrDefault("dpr"), out double dpr)) + { + dpr = dpr.Clamp(1d, 5d); + s.Width = (int)Math.Floor(s.Width * dpr); + s.Height = (int)Math.Floor(s.Height * dpr); + } + if (exists && s.IsEmpty && !folderConfig.ForceProcessing) return; @@ -51,6 +60,7 @@ private async Task mapRequest(object sender, EventArgs e) s.Width = s.Height = 100; ifi = new ImageFileInfo(s.Width > 0 ? s.Width : s.Height, s.Height > 0 ? s.Height : s.Width); + s.SaveFormat = FileFormat.Png; } ifi = ifi ?? await CacheHelper.GetImageInfoAsync(path); @@ -80,8 +90,14 @@ private async Task mapRequest(object sender, EventArgs e) return; } - var cacheVPath = namingStrategy.Value.GetCacheFilePath(path, s); - var cachePath = HostingEnvironment.MapPath(cacheVPath); + if (dpr > 0d && !dic.ContainsKey("quality") && !dic.ContainsKey("q")) + { + dpr = Math.Max(Math.Max((double)s.Width / (rw > 0 ? rw : s.Width), (double)s.Height / (rh > 0 ? rh : s.Height)), 1d); + s.JpegQuality -= (int)Math.Round((dpr - 1d) * 10); + } + + string cacheVPath = namingStrategy.Value.GetCacheFilePath(path, s); + string cachePath = HostingEnvironment.MapPath(cacheVPath); if (File.Exists(cachePath)) {