smsware
smsware

Reputation: 479

BitmapFrameDecode into Image

Recently, I decided to play with Windows Presentation Foundation and create a variation of chess. The whole thing is kinda done (I believe) but it's a long time now as I can't find a way to set my PNG file as a Image control. This is exemplary class which is affected by a issue:

public class Field
{
    public Image Image { get; set; }

    public Image GetImage(String keyName)
    {
        ResourceDictionary imagesDictionary = new ResourceDictionary();
        imagesDictionary.Source = new Uri("file:/[...]/ImagesDictionary.xaml");
        var var = imagesDictionary[keyName];
        Image image = (Image) imagesDictionary[keyName];
        return image;
    }

    public void RefreshImage()
    {
        if (Unit.Subclass.CompareTo("Bishop").Equals(0))
        {
            if (Unit.Player.IsWhite)
            {
                this.Image = this.GetImage("WhiteBishop");
            }
            ...
    }

}

My ImagesDictionary.xaml file:

<ResourceDictionary>
    <ImageSource x:Key="BlackBishop">BlackBishop.png</ImageSource>
    <ImageSource x:Key="WhiteBishop">WhiteBishop.png</ImageSource>
    ...
</ResourceDictionary>

And the issue is that I don't know how to convert the output of GetImage

(System.Windows.Media.Imaging.BitmapFrameDecode)

into the

(System.Windows.Controls.Image)

Any ideas?

Upvotes: 1

Views: 3352

Answers (3)

BadBiki
BadBiki

Reputation: 82

Dim img As New BitmapImage

Using mem As New System.IO.MemoryStream(<InputArrayHere>)
    img.BeginInit()
    img.StreamSource = mem
    img.EndInit()
End Using

return img

Upvotes: 0

Jesse Chisholm
Jesse Chisholm

Reputation: 4025

OK, here is an improved GetImageSource (name changed to reflect its real purpose).

    /// <summary>
    /// Get an ImageSource from the ResourceDictionary  referred to by the
    ///     <paramref name="uriDictionary"/>.
    /// </summary>
    /// <param name="keyName">The ResourceDictionary key of the ImageSource
    ///     to retrieve.</param>
    /// <param name="uriDictionary">The Uri to the XAML file that holds
    ///     the ResourceDictionary.</param>
    /// <returns><c>null</c> on failure, the requested <c>ImageSource</c>
    ///     on success.</returns>
    /// <remarks>If the requested resource is an <c>Image</c> instead of
    ///     an <c>ImageSource</c>,
    /// then the <c>image.Source</c> is returned.</remarks>
    public static ImageSource GetImageSource(String keyName, Uri uriDictionary)
    {
        if (String.IsNullOrEmpty(keyName))
            throw new ArgumentNullException("keyName");
        if (null == uriDictionary)
            throw new ArgumentNullException("uriDictionary");

        ResourceDictionary imagesDictionary = new ResourceDictionary();
        imagesDictionary.Source = uriDictionary;
        var var = imagesDictionary[keyName];
        Object blob = imagesDictionary[keyName];
        Debug.WriteLine(String.Format(
            "error: GetImageSource( '{0}', '{1}' )"
            + " value is: {2}",
            keyName,
            uriDictionary,
            (null == blob) ? "null" : blob.GetType().FullName));
        if (null != blob)
        {
            if (blob is ImageSource)
            {
                return blob as ImageSource;
            }
            if (blob is Image)
            {
                Image image = blob as Image;
                return image.Source;
            }
            if (blob is System.Drawing.Image)
            {
                System.Drawing.Image dImage = blob as System.Drawing.Image;
                MemoryStream mem = new MemoryStream();
                dImage.Save(mem, System.Drawing.Imaging.ImageFormat.MemoryBmp);
                mem.Position = 0;
                BitmapDecoder decode = new BmpBitmapDecoder(
                    mem,
                    BitmapCreateOptions.None,
                    BitmapCacheOption.None);
                return decode.Frames[0];
            }
            Debug.WriteLine(String.Format(
                "error: GetImageSource( '{0}', '{1}' )"
                + " can't handle type: {2}",
                keyName,
                uriDictionary,
                blob.GetType().FullName));
        }
        return null;
    }

And to use it you would do this:

String packText = String.Format("pack://application:,,,/{0};component/{1}",
    Assembly.GetEntryAssembly().FullName,
    "ImageDictionary.xaml");
Uri imageUri = new Uri(packText);
// or if you prefer:
// Uri imageUri = new Uri("file:///.../ImageDictionary.xaml");
//

ImageSource source = GetImageSource(imageKey, imageUri);

if (null != source)
{
    this.Image.Source = source;
}
else
{
    // bail ...
}

The Drawing.Image case will handle BMP, PNG, JPG, GIF, etc., even though I used BmpBitmapDecoder. But be aware that XAML images stretch very prettily but Drawing.Image does not.

-Jesse

Upvotes: 0

Jesse Chisholm
Jesse Chisholm

Reputation: 4025

System.Windows.Media.Imaging.BitmapFrame is derived from ImageSource.

You should be able to do this:

this.Image = new Image();
this.Image.Source = this.GetImage("WhiteBishop");

or

this.Image.Source = this.GetImage("WhiteBishop").Source;

If BitmapFrameDecode is truly derived from System.Windows.Imaging.Image, not from ImageSource.

-Jesse

Upvotes: 1

Related Questions