Blame view

netcore/src/Modularity/Extend/NCC.Extend/OssImageDisplayUrlHelper.cs 3.71 KB
7606a6ad   “wangming”   fix: update produ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  using System;
  using System.IO;
  
  namespace NCC.Extend
  {
      /// <summary>
      /// 阿里云 OSS 图片访问地址:通过 x-oss-process 使用控制台「图片样式」在线缩略(不额外存文件)
      /// </summary>
      public static class OssImageDisplayUrlHelper
      {
          /// <summary>
          /// 默认样式名(与 OSS 控制台「样式规则」名称一致;可通过 NCC_App:AliyunOSS:ThumbnailStyle 覆盖)
          /// </summary>
          public const string DefaultThumbnailStyleName = "samll_img";
  
          /// <summary>
          /// 构建样式处理串:style/样式名
          /// </summary>
          public static string BuildStyleProcess(string styleName)
          {
              var s = string.IsNullOrWhiteSpace(styleName) ? DefaultThumbnailStyleName : styleName.Trim();
              return "style/" + s;
          }
  
          /// <summary>
          /// 作为 URL 查询串追加的片段(已对 value 做转义)
          /// </summary>
          /// <summary>
          /// 生成查询串,与控制台文档一致:<c>?x-oss-process=style/样式名</c>(样式名一般仅字母数字下划线,不整体编码)
          /// </summary>
          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;
          }
  
          /// <summary>
          /// 是否可对扩展名做在线缩略(排除 svg 等)
          /// </summary>
          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";
          }
  
          /// <summary>
          /// 在图片 URL 后追加 OSS 图片处理参数,得到缩略图地址
          /// </summary>
          /// <param name="url">完整 http(s) 地址或站内 /api/File/Image/... 相对路径</param>
          /// <param name="extensionHint">扩展名提示(如 jpg),相对路径且无后缀时可传</param>
          /// <param name="ossImageStyleName">OSS 控制台图片样式名称,空则用 <see cref="DefaultThumbnailStyleName"/></param>
          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}";
          }
      }
  }