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}";
}
}
}