【问题标题】:Validating WPF Bitmap Image Loaded from URI at Runtime在运行时验证从 URI 加载的 WPF 位图图像
【发布时间】:2012-05-01 05:11:06
【问题描述】:

我试图在运行时从 URI 加载 BitmapImage。我在我想通过数据绑定替换的 XAML 用户控件中使用默认图像。这行得通。

我遇到的问题是在替换图像使用无效文件的情况下(可能是错误的 URI,或者 URI 指定了非图像文件)。发生这种情况时,我希望能够检查 BitmapImage 对象以查看它是否已正确加载。如果没有,我想坚持使用的默认图像。

这是 XAML:

<UserControl x:Class="MyUserControl">
    <Grid>
        <Image
            x:Name="myIcon"
            Source="Images/default.png" />
    </Grid>
</UserControl>

以及相关的代码隐藏:

public static readonly DependencyProperty IconPathProperty =
    DependencyProperty.Register(
        "IconPath",
        typeof(string),
        typeof(MyUserControl),
        new PropertyMetadata(null, new PropertyChangedCallback(OnIconPathChanged)));

public string IconPath
{
    get { return (string)GetValue(IconPathProperty); }
    set { SetValue(IconPathProperty, value); }
}

private static void OnIconPathChanged(
    object sender,
    DependencyPropertyChangedEventArgs e)
{
    if (sender != null)
    {
        // Pass call through to the user control.
        MyUserControl control = sender as MyUserControl;
        if (control != null)
        {
            control.UpdateIcon();
        }
    }
}

public void UpdateIcon()
{
    BitmapImage replacementImage = new BitmapImage();

    replacementImage.BeginInit();
    replacementImage.CacheOption = BitmapCacheOption.OnLoad;

    // Setting the URI does not throw an exception if the URI is
    // invalid or if the file at the target URI is not an image.
    // The BitmapImage class does not seem to provide a mechanism
    // for determining if it contains valid data.
    replacementImage.UriSource = new Uri(IconPath, UriKind.RelativeOrAbsolute);

    replacementImage.EndInit();

    // I tried this null check, but it doesn't really work.  The replacementImage
    // object can have a non-null UriSource and still contain no actual image.
    if (replacementImage.UriSource != null)
    {
        myIcon.Source = replacementImage;
    }
}

下面是我如何在另一个 XAML 文件中创建此用户控件的实例:

<!--
  My problem:  What if example.png exists but is not a valid image file (or fails to load)?
-->
<MyUserControl IconPath="C:\\example.png" />

或者也许有人可以建议一种不同/更好的方法来在运行时加载图像。谢谢。

【问题讨论】:

    标签: c# wpf xaml code-behind bitmapimage


    【解决方案1】:

    这很粗略,但我发现一个无效的 BitmapImage 的宽度和高度都是 0。

        BitmapImage image;
        if(image.Width > 0 && image.Height > 0) 
        {  
            //valid image 
        }     
    

    【讨论】:

    • 是的,这是一个 hack,但在我找到更好的解决方案之前,我会使用它。并且不知道为什么BitmapImage.cs没有CheckCache作为公共方法,或者CreationCompletedDone事件或类似的downloadsuccess和downloadfailed在很多情况下是不够的。在我写这篇文章时,我应该检查宽度 > 1 和高度 > 1,而不是 0。感谢您的解决方案。
    【解决方案2】:

    好吧,BitmapImage 类有两个事件,当下载或解码失败时会引发这些事件。

    yourBitmapImage.DownloadFailed += delegate { /* fall to your def image */ }
    yourBitmapImage.DecodeFailed += delegate { /* fall to your def img */ }
    

    附带说明,如果您尝试实现后备占位符:http://www.markermetro.com/2011/06/technical/mvvm-placeholder-images-for-failed-image-load-on-windows-phone-7-with-caliburn-micro/ 似乎不错。

    【讨论】:

      【解决方案3】:

      这已经回答了。请查看thisthis。我认为他们俩都在某种程度上回答了您的问题,但我更喜欢前一种方法,因为它甚至会检查远程资源的 contentType。

      你也可以看看这个post

      更新:

      在本地文件的情况下,这可以通过简单地使用 Uri 或路径创建一个 Image 对象来检查。如果成功,则说明图片是合法图片:

      try
      {
          Image image = Image.FromFile(uri);
          image.Dispose();
      }
      catch (Exception ex)
      {
          //Incorrect uri or filetype.
      }
      

      【讨论】:

      • 我认为这些解决方案不适用于我的情况,因为我使用指向本地文件的 URI(没有通过 HTTP)。我实际上在您的第一个链接中尝试了该解决方案,它引发了一个异常,指出无法识别 URI 前缀。我使用的 URI 字符串的类型为:“pack://application:,,,/ReferencedAssembly;component/ResourceFile.xaml”
      • @RobotNerd 你找到解决办法了吗?
      【解决方案4】:

      你可以试试这个检查

              if (bitmapImage.UriSource==null || bitmapImage.UriSource.ToString()).Equals(""))
              {
                  Console.WriteLine("path null");
              }
              else
              {
                  bitmapImage.EndInit();
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-04
        • 2017-06-11
        • 2012-08-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多