OssImageDisplayUrlHelper.cs
3.71 KB
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}";
}
}
}