You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Umbraco媒体服务保存事件获取图片宽高并验证比例

在Umbraco中上传前验证图片宽高比的实现方案

没问题,这个需求完全可以实现!你不用纠结直接把mediaItem转成Image类型,反而应该从上传的文件流入手来获取宽高——毕竟在保存事件触发时,媒体项可能还没真正写入磁盘,直接操作流更可靠。下面给你详细的实现步骤和代码示例:

核心思路

通过订阅Umbraco的MediaService.Saving事件,在媒体项保存前拦截上传的图片文件流,使用图片处理库读取宽高,再验证是否符合目标比例。推荐用ImageSharp(跨平台友好)来处理图片,避免System.Drawing.Common的平台限制问题。

具体实现步骤

1. 安装ImageSharp NuGet包

首先在项目中安装ImageSharp:

Install-Package SixLabors.ImageSharp
# 或者用.NET CLI
dotnet add package SixLabors.ImageSharp

2. 编写事件处理逻辑

创建一个Composer来注册媒体保存事件,然后在事件方法中完成宽高验证:

using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using SixLabors.ImageSharp;
using System.Linq;
using System;

public class ImageValidationComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        // 订阅媒体保存前的事件
        builder.MediaService.Saving += MediaService_Saving;
    }

    private void MediaService_Saving(IMediaService sender, MediaSavingEventArgs e)
    {
        // 仅处理图片类型的媒体项(替换成你项目中的图片媒体类型别名,默认是"Image")
        const string imageMediaTypeAlias = "Image";
        if (e.Media.ContentType.Alias != imageMediaTypeAlias)
            return;

        // 获取图片文件属性(默认的图片文件属性别名是"umbracoFile")
        var fileProperty = e.Media.Properties.FirstOrDefault(p => p.Alias == "umbracoFile");
        if (fileProperty == null || fileProperty.Value == null)
            return;

        // 从属性中提取文件流
        if (fileProperty.Value is IContentFile contentFile)
        {
            using var fileStream = contentFile.OpenStream();
            // 读取图片宽高
            using var image = Image.Load(fileStream);
            int imageWidth = image.Width;
            int imageHeight = image.Height;

            // 定义目标宽高比(示例:16:9)
            const double targetAspectRatio = 16.0 / 9.0;
            double actualAspectRatio = (double)imageWidth / imageHeight;

            // 允许一定的误差范围(比如±0.05,避免严格比例导致的用户困扰)
            const double tolerance = 0.05;
            if (Math.Abs(actualAspectRatio - targetAspectRatio) > tolerance)
            {
                // 取消保存操作并提示错误信息
                e.Cancel = true;
                e.Message = $"图片宽高比不符合要求!当前比例为{imageWidth}:{imageHeight},需要接近16:9的比例";
            }
        }
    }
}

关键注意事项

  • 媒体类型/属性别名:要确保代码中的imageMediaTypeAlias和umbracoFile与你项目中的实际配置一致,如果自定义了媒体类型或属性,记得修改对应的别名。
  • 版本兼容性:如果是Umbraco v8版本,IContentFile的处理方式略有不同,你需要从MediaSavingEventArgs.Files集合中获取上传的文件流,示例代码可以调整为:
    if (e.Files.Any())
    {
        var uploadedFile = e.Files.First();
        using var stream = uploadedFile.OpenReadStream();
        // 后续读取宽高的逻辑一致
    }
    
  • 异常处理:实际项目中可以添加try-catch块,避免因损坏的图片文件导致事件崩溃。

内容的提问来源于stack exchange,提问作者luxor37

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:20:50