2

I'm pretty new to displaying images in WPF forms, and i'm having trouble when it comes to converting and assigning an Image source for my GUI.

        System.Drawing.Image testImg = ImageServer.DownloadCharacterImage(charID, ImageServer.ImageSize.Size128px);
        byte[] barr = imgToByteArray(testImg);
        CharImage.Source = ByteToImage(barr);          

    public byte[] imgToByteArray(System.Drawing.Image testImg)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            testImg.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);
            return ms.ToArray();
        }
    }

    public System.Drawing.Image ByteToImage(byte[] barr)
    {
        MemoryStream ms = new MemoryStream(barr);
        System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
        return returnImage;
    }

So i take in an image (JPEG) from the EVE Online C# API Library and then try to convert it to a byte array and back to a proper image. However i always get this error: "Cannot Implicitly convert type 'System.Drawing.Image' to 'System.Windows.Media.ImageSource'" I'm completely dumbfounded on how to solve this.

2 Answers 2

3

One possible solution is to save the image files (for example, .jpg) as WPF embedded resource and then use the following code snippet to get BitmapImage:

Listing 1. Get BitmapImage from EmbeddedResource

private string GetAssemblyName()
{
    try { return Assembly.GetExecutingAssembly().FullName.Split(',')[0]; }
    catch { throw; }
}

private BitmapImage GetEmbeddedBitmapImage(string pathImageFileEmbedded)
{
    try
    {
        // compose full path to embedded resource file
        string _fullPath = String.Concat(String.Concat(GetAssemblyName(), "."), pathImageFileEmbedded);

        BitmapImage _bmpImage = new BitmapImage();
        _bmpImage.BeginInit();
        _bmpImage.StreamSource = Assembly.GetExecutingAssembly().GetManifestResourceStream(_fullPath);
        _bmpImage.EndInit();
        return _bmpImage;
    }
    catch { throw; }
    finally { }
}

Correspondingly, set the Source property of the WPF Image control (for example, Image1) to that BitmapImage returned by function:

Image1.Source = GetEmbeddedBitmapImage(_strEmbeddedPath);

Note: you should reference the following:

using System.Windows.Media.Imaging;
using System.Reflection;

Another possible solution is to get the BitmapImage from image file using Uri object as shown in the following code snippet (Listing 2):

Listing 2. Get BitmapImage from File (use Uri)

private BitmapImage GetBitmapImageFromFile(string ImagePath)
{
    Uri BitmapUri;
    StreamResourceInfo BitmapStreamSourceInfo;
    try
    {
        // Convert stream to Image.
        BitmapImage bi = new BitmapImage();
        BitmapUri = new Uri(ImagePath, UriKind.Relative);
        BitmapStreamSourceInfo = Application.GetResourceStream(BitmapUri);
        bi.BeginInit();
        bi.StreamSource = BitmapStreamSourceInfo.Stream;
        bi.EndInit();
        return bi;
    }
    catch { throw; }
}

Hope this may help.

Sign up to request clarification or add additional context in comments.

4 Comments

So where in this would i be putting the image itself? Sorry pretty new to WPF so I'm Out of my depth here
Don't forget to set bi.CacheOption = BitmapCacheOption.OnLoad;, otherwise the image may not be loaded by the time you need to display it. You'd think the framework would know to do this but it's caught me out a few times.
You should have some Image control placed in XAML Grid and named for example <Image Name="Image1"...> Apply that BitmapImage to its property Image1.Source. Best regards,
Far better than an Embedded Resource is a plain Resource. Then you would load a BitmapImage from a Resource File Pack URI like new BitmapImage(new Uri("pack://application:,,,/Images/Test.jpg"));
2

System.Drawing.Image is WinForms, not WPF. Your ByteToImage method should return BitmapSource instead.

The probably easiest way to create a BitmapSource from a byte array is BitmapFrame.Create:

public BitmapSource ByteArrayToImage(byte[] buffer)
{
    using (var stream = new MemoryStream(buffer))
    {
        return BitmapFrame.Create(stream,
            BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
    }
}

You would assign the return value of the above method to the Source property of an Image control:

image.Source = ByteArrayToImage(barr);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.