using System; using System.IO; namespace NCC.Extend { /// /// 阿里云 OSS 图片访问地址:通过 x-oss-process 使用控制台「图片样式」在线缩略(不额外存文件) /// public static class OssImageDisplayUrlHelper { /// /// 默认样式名(与 OSS 控制台「样式规则」名称一致;可通过 NCC_App:AliyunOSS:ThumbnailStyle 覆盖) /// public const string DefaultThumbnailStyleName = "samll_img"; /// /// 构建样式处理串:style/样式名 /// public static string BuildStyleProcess(string styleName) { var s = string.IsNullOrWhiteSpace(styleName) ? DefaultThumbnailStyleName : styleName.Trim(); return "style/" + s; } /// /// 作为 URL 查询串追加的片段(已对 value 做转义) /// /// /// 生成查询串,与控制台文档一致:?x-oss-process=style/样式名(样式名一般仅字母数字下划线,不整体编码) /// public static string ThumbnailProcessQueryForStyle(string styleName) { var s = string.IsNullOrWhiteSpace(styleName) ? DefaultThumbnailStyleName : styleName.Trim(); foreach (var c in s) { if (!(char.IsLetterOrDigit(c) || c == '_' || c == '-' || c == '.')) return "x-oss-process=" + Uri.EscapeDataString(BuildStyleProcess(styleName)); } return "x-oss-process=style/" + s; } /// /// 是否可对扩展名做在线缩略(排除 svg 等) /// public static bool IsRasterImageExtension(string ext) { if (string.IsNullOrWhiteSpace(ext)) return false; var e = ext.Trim().TrimStart('.').ToLowerInvariant(); return e is "jpg" or "jpeg" or "png" or "gif" or "webp" or "bmp" or "tiff"; } /// /// 在图片 URL 后追加 OSS 图片处理参数,得到缩略图地址 /// /// 完整 http(s) 地址或站内 /api/File/Image/... 相对路径 /// 扩展名提示(如 jpg),相对路径且无后缀时可传 /// OSS 控制台图片样式名称,空则用 public static string AppendThumbnailToUrl(string url, string extensionHint = null, string ossImageStyleName = null) { if (string.IsNullOrWhiteSpace(url)) return url; if (url.IndexOf("x-oss-process=", StringComparison.OrdinalIgnoreCase) >= 0) return url; var ext = extensionHint; if (string.IsNullOrWhiteSpace(ext)) { try { if (url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { ext = Path.GetExtension(new Uri(url).AbsolutePath); } } catch { // ignore } } if (string.IsNullOrWhiteSpace(ext)) ext = Path.GetExtension(url.Split('?', '#')[0]); if (!IsRasterImageExtension(ext)) return url; var q = ThumbnailProcessQueryForStyle(ossImageStyleName); return url.Contains("?", StringComparison.Ordinal) ? $"{url}&{q}" : $"{url}?{q}"; } } }