Skip to the content.

媒体处理

引用 MS.Microservice.Media 可处理静态图片、添加图片/视频水印、生成和识别二维码、编辑与拼接视频。图片/视频自动去水印、区域修复、OCR、表格、抠图和超分辨率使用可选的 MS.Microservice.Media.Inference。两者均使用 .NET 10。

入口 功能
ImageProcessor.ProcessAsync EXIF 方向校正、裁剪、旋转、翻转、缩放,输出 PNG/JPEG/WebP
ImageWatermarker.AddTextAsync / AddLogoAsync 图片文字/Logo 水印;透明 PNG 叠加图可供其他流程复用
CodeProcessor.GenerateAsync / DecodeAsync 八种二维码/条码生成及多码识别
WatermarkRemover.RemoveAsync(可选) 默认自动检测并修复图片,也可提供手动蒙版
MiganInpainter.InpaintAsync(可选) 按二值蒙版修复指定区域
OcrProcessor.RecognizeAsync(可选) 本地中英文印刷体识别,返回文字及四角坐标;接入示例
TableRecognizer.RecognizeAsync(可选) 带线框表格的行列、合并跨度及单元格文字;接入示例
BiRefNetBackgroundRemover.RemoveAsync(可选) 抠图为透明 PNG 与软蒙版,可再换纯色背景;资源要求与示例
Swin2SrUpscaler.UpscaleAsync(可选) 本地 2 倍超分辨率,输出透明 PNG;接入示例
VideoWatermarkRemover.RemoveAsync(可选) 默认自动检测,支持手动蒙版/矩形关键帧,生成 FFV1 MKV 及预览包
VideoProcessor.ProbeAsync / ProcessAsync 视频信息、剪辑、画面变换、MP4/MKV/WebM 转码
AddTextWatermarkAsync / AddLogoWatermarkAsync 视频水印及显示时间范围
ConcatenateAsync 按顺序拼接不同尺寸、帧率、编码和音轨的视频
CaptureFrameAsync / ExtractAudioAsync 封面截图和指定音轨提取

图片编辑与水印

using MS.Microservice.Media.Images;

await using var input = File.OpenRead("input.jpg");
await using var output = File.Open("scaled.webp", FileMode.CreateNew, FileAccess.Write);
await new ImageProcessor().ProcessAsync(input, output,
    new ImageProcessingOptions
    {
        Resize = new(1280, 720),
        ResizeMode = ImageResizeMode.Contain,
        Format = ImageOutputFormat.Webp,
        Quality = 85
    }, cancellationToken);
ImageProcessingOptions 参数 默认值 说明
Crop 不裁剪 使用 EXIF 校正后的整数像素坐标,必须位于图片内
Resize / ResizeMode 不缩放 / Contain Contain 保持比例适配,Cover 居中裁剪填满,Stretch 拉伸
RotationDegrees 0 只接受 0、90、180、270 度,顺时针旋转
FlipHorizontal / FlipVertical false 在旋转后画面上翻转
Format / Quality PNG / 90 质量范围 0–100;PNG 无损,质量参数不控制其文件大小
JpegBackground 白色 JPEG 的不透明合成底色;PNG/WebP 保留透明度
BackgroundColor 不设置 为 PNG/JPEG/WebP 合成不透明纯色底;设置时优先于 JpegBackground
Limits 16,384 单边 / 40M 像素 / 64 MiB 输入 输入和输出画布均受尺寸、像素预算约束

为透明图片换纯色背景时,设置 BackgroundColor = new ImageColor(255, 255, 255) 并选择输出格式;底色必须不透明,最终画布没有透明像素。未设置时,PNG/WebP 继续保留 alpha,JPEG 使用 JpegBackground。

添加图片水印时,传入 TextWatermark 或 Logo 流。文字的 FontSize 默认 32,颜色默认白色;中文应指定已部署的 FontFile。默认字体缺字会报错,不会悄悄换字体。Logo 可用 ImageSize 指定等比例适配框。

WatermarkPlacement 参数 默认值 说明
Anchor / MarginX / MarginY 右下 / 16 / 16 九宫格锚点及四周内边距,按旋转后的外框定位
Opacity / RotationDegrees 0.35 / 0 透明度 0–1,水印角度可为任意有限值
Tile / TileGap / MaximumTiles false / 32 / 10,000 平铺时按外框加间隔排布,边缘可裁剪;非平铺必须完整放入画面

文字限一行、4096 个 UTF-16 单元,支持单个文本 run 的 HarfBuzz 塑形;复杂混合双向文字应先由排版组件生成透明 Logo。静态图片入口拒绝多帧动画,输出不复制原 EXIF 等元数据。

二维码与条形码

using MS.Microservice.Media.Codes;

var codes = new CodeProcessor();
await using (var png = File.Open("code.png", FileMode.CreateNew, FileAccess.Write))
    await codes.GenerateAsync("你好,微服务", png,
        new CodeGenerationOptions { Format = CodeFormat.Qr, Width = 256, Height = 256 }, cancellationToken);
await using var codeInput = File.OpenRead("code.png");
var found = await codes.DecodeAsync(codeInput, cancellationToken: cancellationToken);
参数 默认值 说明
Format QR 另支持 Code128、EAN13、EAN8、UPC-A、Code39、DataMatrix、PDF417
Width / Height 256 / 256 输出 PNG 尺寸;过小会失败,不压缩码元来凑尺寸
Margin null 使用格式默认值;DataMatrix 为一模块静区,显式值的单位因格式而异
QrErrorCorrection Medium QR 的四档纠错级别
Foreground / Background 黑 / 白 均须不透明,前景应比背景暗
MaximumTextCharacters 4096 编码内容的 UTF-16 单元上限
Formats(识别) 全部 可缩小码制范围;默认尝试旋转、反色及更充分搜索

未找到码返回空集合;定位点属于 EXIF 校正后的图片。其他码制的字符、长度和校验位约束由 ZXing 验证,低对比度或静区不足会影响识别。

视频处理

先由宿主安装带所需编码器的 FFmpeg 和 ffprobe。可配置绝对路径,不能把外部请求作为可执行文件路径。

using MS.Microservice.Media.Images;
using MS.Microservice.Media.Video;

var video = new VideoProcessor(new FfmpegOptions
{
    FfmpegPath = "ffmpeg", FfprobePath = "ffprobe"
});
await video.ProcessAsync("input.mp4", "edited.mp4", new VideoEditOptions
{
    Start = TimeSpan.FromSeconds(2), Duration = TimeSpan.FromSeconds(5),
    Resize = new(1280, 720)
}, cancellationToken);
await video.AddTextWatermarkAsync("edited.mp4", "marked.mp4",
    new TextWatermark("内部资料") { FontFile = "fonts/NotoSansSC-Regular.ttf", FontSize = 28 },
    new VideoWatermarkOptions { Start = TimeSpan.FromSeconds(1), End = TimeSpan.FromSeconds(4) },
    cancellationToken);
await using var logo = File.OpenRead("logo.png");
await video.AddLogoWatermarkAsync("edited.mp4", "with-logo.mp4", logo, new(120, 120),
    cancellationToken: cancellationToken);
await video.ConcatenateAsync(new[] { "edited.mp4", "marked.mp4" }, "joined.mp4",
    new VideoConcatenationOptions { Canvas = new(1280, 720), FrameRate = 30 }, cancellationToken);
await video.CaptureFrameAsync("joined.mp4", "cover.jpg", TimeSpan.FromSeconds(1),
    cancellationToken: cancellationToken);
await video.ExtractAudioAsync("joined.mp4", "audio.wav", cancellationToken: cancellationToken);

示例中的字体文件由宿主提供。MP4/MKV 输出 H.264 + AAC,WebM 输出 VP9 + Opus,须有对应编码器;FFmpeg 的分发条件取决于所选构建。

参数组 默认值 说明
FfmpegOptions.Timeout 30 分钟 单次进程超时,可设 Timeout.InfiniteTimeSpan
编辑 Start / Duration 0 / 到末尾 非负起点、正时长;图片变换选项的坐标以方向校正后的画面为准
ConstantRateFactor / Speed 23 / Fast CRF 0–51;速度另有 Balanced、Slow
视频水印 Start / End 0 / 到末尾 显示区间 [Start, End),不延长源视频;位置用 Placement
拼接 Canvas / FrameRate 取首段 画布补为偶数;平均帧率未知时须指定,范围为 (0, 240]
拼接 MaximumInputs 32 允许单段和重复段,要求已知正时长
视频 MaximumDimension / MaximumPixels 16,384 / 40M 输入、画布及补齐外框预算;水印使用 Placement.Limits
提取 AudioTrackIndex 0 音频轨自身的零基索引;WAV 为 PCM16,另支持 MP3/M4A/FLAC

视频文件入口不覆盖已有目标,成功校验后才发布。YUV420 输出会在右侧/底部将奇数尺寸补齐一像素;重新编码有损,不保证原像素、HDR 色彩或绝对时间戳保留。编辑与水印不强制恒定帧率;拼接统一为恒定帧率,并将每段音视频各自首帧归零,不保留源音画起始偏移。任一片段有声音时,拼接输出一个 48 kHz 立体声音轨,仅取各段第一音轨;其他音轨和字幕不属于拼接保留范围。

截图选择不早于指定时刻的第一帧,末尾没有后续帧时会报错。音轨提取保留源采样率和声道,MP3 仅接受单/双声道;所选编码器不支持该采样率时失败,可改用 WAV/FLAC。

图片/视频自动去水印

选装 Media.Inference 后,图片和视频的 RemoveAsync 默认自动检测并修复,同时生成可检查的蒙版;手动模式接受白色编辑、黑色保留的二值蒙版,视频另支持矩形关键帧。需要本地模型和 Python 环境,运行时不下载权重或上传图片。

当前检测模型针对重复文字水印,会误选正常文字、字幕或场景 Logo,也可能漏选水印。结果始终建议人工检查,应保留原片、展示蒙版并允许手动纠正。每次自动调用有独立 Python 冷启动和模型加载开销,应按后台任务规划;修复生成的是合理内容,不能恢复被遮挡的真实像素。视频结果包含 FFV1 MKV、蒙版预览和逐帧记录,可再明确转码为 MP4。

所有权与维护

图片、二维码和修复接口从当前位置读写流并保持打开,输入输出须使用不同底层资源;仅创建不同流对象不能保证文件不同。失败或取消可能留下部分输出,宿主应先写临时结果再发布。图片编码输出大小没有按输入文件大小保证,并发、总内存和保留策略由宿主控制。Skia/HarfBuzz 原生库及字体须适配目标系统,像素预算不等于进程内存硬配额。

使用者接入见组件消费。实现与回归说明:图片管道、图片水印、Codes 坐标、视频进程与编辑、视频水印、截图与音轨、视频拼接。