如何使用 Umbraco 媒体服务保存事件获取图像宽度

How to get image width with Umbraco Media Service Saving Event

我正在寻找一种通过 Umbraco 事件获取图像宽度的方法,以在上传之前验证图像是否符合特定的纵横比。问题是我不知道是否可以将 mediaItem 转换为 Image。到目前为止,我如何获得宽度或高度是我的事件代码:

public class ImageResizer : ApplicationEventHandler
{
    protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
        MediaService.Saving += MediaServiceSaving;
    }
    void MediaServiceSaving(IMediaService sender, SaveEventArgs<IMedia> e)
    {
        foreach (var mediaItem in e.SavedEntities)
        {
            Image img = (Image)mediaItem;
            double height = img.Height;
            double width = img.Width;
            string msg = "" + height;
            if (height / width != 1)
            {
                msg = "Ratio is not 1:1. Please make sure the width and height of your image is the same.";
                BasePage.Current.ClientTools.ShowSpeechBubble(BasePage.speechBubbleIcon.success, "Error", msg);
            }
            else
            {
                //Ducplicate image to images and thubnails of desired choice
                //Send images to database - continue normal process
            }
        }
    }
}

你真的不能这样做。首先,IMedia 不一定是图片——它可以是任何东西(视频、pdf、zip 等等)。它只是保存在 Umbraco 媒体库中的一个项目。实际上,您甚至可以说 Umbraco 媒体项目甚至不需要附加文件(如果您愿意,它也可能有多个文件)。

此外 - 即使媒体项目实际上是图像,您也不能简单地将其转换为 .NET Image class,因为它们实际上不是一回事。

您想验证上传的图像是否符合特定比例,然后才能保存它。虽然您可以在 Umbraco 中看到上传图像的比例,但在您的代码 运行ning 时,这并不是总是可用的。保存媒体项目时,您挂钩的事件会触发。

与您的事件处理程序一起,另一个事件处理程序也附加到这个确切的事件。这个另一个事件处理程序负责根据上传图像的尺寸添加 umbracoWidthumbracoHeight 属性。因此,您不能真正依赖这些属性在您的代码 运行ning 时始终被分配和可用。您不知道这些事件 运行 进入的确切顺序,或者这些维度是否在 您的 代码被命中的那一刻实际保留。

为了做你想做的事,你需要访问正在保存的文件数据,并从中生成内存中的 Image 并使用它来检查图像的尺寸正在上传。

总而言之,我真的不认为你在这里的尝试是解决这个问题的最好方法。如果有人上传多张图片,但只允许上传一半 - 您将如何处理这种情况? 当仅仅显示通知气泡时,用户并不清楚哪些文件是正确的,哪些文件不正确。除此之外 - 你并没有真正阻止上面代码示例中的任何内容。您只是在显示通知错误 - 但即使比例不正确,文件仍会被保存。

然后是连接到一般事件的问题,例如媒体服务上的 Saving 事件。这用于保存任何类型的媒体 - 所以首先你需要确保你的代码只 运行s 在你想要它 运行 的东西上。这意味着仅在实际上传图像时将其限制为 运行。但是,您也很可能希望将其限制为仅 运行 发生在特定情况下的上传(无论如何,您似乎不太可能只希望上传适合 1:1 比率)。

我认为解决您问题的最佳方法是考虑为媒体库创建一个自定义图像上传编辑器,该编辑器可以直接在 javascript 中检查图像是否符合您的比率要求。这将确保您可以以一种很好的方式处理人们试图输入尺寸不正确的图像的情况 - 在甚至让他们尝试保存媒体项目之前显示警告并使 UI 的状态无效。

它在不干扰 所有 媒体保存的方式上也将更加灵活 - 代码将仅处理此特定 属性 编辑器用于上传。


我还强烈建议您花一点时间研究 ImageProcessor 的功能和 Umbraco 中的图像裁剪器。它基本上允许您设置您想要的图像的特定 pre-set 尺寸。上传图像时,您可以精确指定您希望该图像如何成为特定尺寸的 cropped/resized。然后可以在您的标记中使用这些裁剪,Umbraco 将确保以您在模板中请求的特定大小调整大小、裁剪、缓存和输出您站点中的图像。

您可以在此处阅读更多相关信息:https://our.umbraco.org/documentation/getting-started/backoffice/property-editors/built-in-property-editors/image-cropper

只要相信 Umbraco 并让它完成确定它是否是图像的艰苦工作:

public class ImageResizer : ApplicationEventHandler
{
        protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            MediaService.Saving += MediaServiceSaving;
        }
        void MediaServiceSaving(IMediaService sender, SaveEventArgs<IMedia> e)
        {
            foreach (var mediaItem in e.SavedEntities)
            {
                //if it's an image, the content type will tell you.
                if(mediaItem.ContentType.Alias == "Image")
                {
                    var width = Convert.ToDouble(mediaItem.Properties["umbracoWidth"].Value);
                    var height = Convert.ToDouble(mediaItem.Properties["umbracoHeight"].Value);

                    if (height / width != 1)
                    {                        
                  //Sending a message will cancel the process, so you don't
                  //need an else (unless you want to do something else with the image of course.
                        e.Messages.Add(new EventMessage("Wrong Ratio", "Ratio is not 1:1. Please make sure the width and height of your image is the same.", EventMessageType.Error));                        
                    }                    
                }
            }
        }
}