【问题标题】:What is the best way to determine if WPF can load an image file?确定 WPF 是否可以加载图像文件的最佳方法是什么?
【发布时间】:2023-03-15 23:05:01
【问题描述】:

有什么方法可以确定 WPF 是否能够在不尝试构造 BitmapImage 并在失败时捕获异常的情况下加载图像文件?

我正在创建一个图像浏览器,它试图显示可移动驱动器上所有图像的预览。可能有很多不是图像的文件,并且为每个文件捕获异常似乎效率低下,但我想不出一种不易出错的方法。

有什么建议吗?

谢谢, 标记

【问题讨论】:

标签: c# .net wpf


【解决方案1】:

我最近问了一个非常相似的问题并得到了很好的答案here

基本上,您可以在用户的​​机器上找到 BitmapImage 可以用来打开各种图像格式的所有编解码器。从这些编解码器中,您可以构建这些可以打开的文件扩展名列表。

然后,当您的程序尝试打开一个文件时,对照此列表检查该文件的扩展名。

WPF 使用 WIC 来处理图像。它包含一组处理常见图像格式的核心编解码器,我相信您可以从here 硬编码这些扩展。 WIC 也是可扩展的,例如,相机制造商可以将自定义图像格式合并到 WIC 中。 the answer above 中的代码会在您的计算机中搜索这些额外的编解码器,并为它们提供相应的文件扩展名。

此方法假定文件的文件扩展名是正确的。在大多数情况下,这通常是一个公平的假设——即使是 Windows 资源管理器也乐于假设这一点。尽管如此,如果奇怪的流氓文件出现在扩展名似乎是图像的位置,我仍会将 BitmapImage 构造包装在 try-catch 中,但它仍然无法打开。

编辑:我还将此功能封装到一个类中,您可以将其复制粘贴到您自己的项目here

【讨论】:

    【解决方案2】:

    WPF 使用 WIC,你想要的是演示 in C++ in the MSDN 但框架的反编译源显示 IWICImagingFactory::CreateComponentEnumerator 甚至没有暴露在框架的内部类中。

    您最好的解决方案是创建一个支持的扩展的静态列表(WIC 支持开箱即用的格式是on MSDN)并使用它。

    【讨论】:

      【解决方案3】:

      首先,您可以尝试检查图像文件扩展名以验证您的应用程序是否能够读取它。

      那你要读Validate image from file in C#

      这里是Getting image dimensions without reading the entire file

      【讨论】:

      【解决方案4】:

      我在 StackOverflow 上的另一个问题中找到了答案,但我不记得我是从哪个问题中得到答案的。无论如何,这是我根据该问题的一个答案所说的内容编写的一些代码:

      public static string GetImageFileExtension( byte[] plateImage ) {
          string imageFileExtension = String.Empty;
          using ( Stream ms = new MemoryStream( plateImage ) ) {
              BitmapDecoder decoder = BitmapDecoder.Create( ms, BitmapCreateOptions.None, BitmapCacheOption.None );
                   if ( decoder is BmpBitmapDecoder  ) imageFileExtension = ".bmp";
              else if ( decoder is GifBitmapDecoder  ) imageFileExtension = ".gif";
              else if ( decoder is IconBitmapDecoder ) imageFileExtension = ".ico";
              else if ( decoder is JpegBitmapDecoder ) imageFileExtension = ".jpg";
              else if ( decoder is PngBitmapDecoder  ) imageFileExtension = ".png";
              else if ( decoder is TiffBitmapDecoder ) imageFileExtension = ".tiff";
              else if ( decoder is WmpBitmapDecoder  ) imageFileExtension = ".wmp";
          }
          return imageFileExtension;
      }
      

      这在生产代码中效果很好。

      【讨论】:

      • 但是如果文件不是图像会发生什么?我认为 BitmapDecoder.Create 会抛出一个异常,这是我试图避免的。
      • 在我的应用程序中,byte 数组将始终包含某种位图,所以我没有这个问题。在这种情况下,处理异常的唯一其他方法是编写自己的类来解析位图标题。我猜你已经完成了哪个?
      • 检查 BitmapDecoder.Create 方法的文档表明没有列出任何异常。如果Stream 中的数据在这种情况下不是图像,我不知道该函数会做什么。
      猜你喜欢
      • 2023-03-18
      • 2017-10-21
      • 1970-01-01
      • 2012-04-04
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 2020-09-07
      • 1970-01-01
      相关资源
      最近更新 更多