Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validating WPF Bitmap Image Loaded from URI at Runtime

I am trying to load a BitmapImage at runtime from a URI. I use a default image in my XAML user control which I'd like to replace via databindings. This works.

The problem I'm having is in situations where an invalid file is used for the replacement image (maybe it's a bad URI, or maybe the URI specifies a non-image file). When this happens, I want to be able to check the BitmapImage object to see if it was correctly loaded. If not, I want to stick to the default image being used.

Here's the XAML:

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

And the relevant codebehind:

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;
    }
}

And here's how I might create an instance of this user control in another XAML file:

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

Or maybe someone can suggest a different/better way to go about loading an image at runtime. Thanks.

like image 973
RobotNerd Avatar asked Mar 10 '26 09:03

RobotNerd


2 Answers

It's crude, but I found that a non-valid BitmapImage will have width and height of 0.

    BitmapImage image;
    if(image.Width > 0 && image.Height > 0) 
    {  
        //valid image 
    }     
like image 163
James R Avatar answered Mar 11 '26 22:03

James R


Well, BitmapImage class has two events, which will be raised when either download or decoding has failed.

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

On a side note, if you're trying to implement fallback placeholder: http://www.markermetro.com/2011/06/technical/mvvm-placeholder-images-for-failed-image-load-on-windows-phone-7-with-caliburn-micro/ seems nice.

like image 41
Erti-Chris Eelmaa Avatar answered Mar 11 '26 21:03

Erti-Chris Eelmaa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!