Reputation: 479
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
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
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
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