3

I have read lots of examples. And what I have seems right. But when it comes to loading it fails.

Here is my code:

LargeImage=new BitmapImage(new Uri("pack://application:,,,/Images/books_48.png"))

This code runs in AssemblyA. AssemblyA's project also has a folder in it called Images. That folder has a file called books_48.png. It is set to compile as "Resource" and never copy.

I used DotPeek to see if the Image is in the AssemblyA.dll and it is there.

The first reference to LargeImage is in AssemblyB. It binds LargeImage to a FluentRibbon Fluent:Button.LargeIcon.

When it comes time to load the BitmapImage I get this error:

Cannot locate resource 'images/books_48.png'.

Any ideas on how to get this to load?

NOTE: I have also tried these:

"pack://application:,,,/AssemblyA;component/Images/books_48.png"
"pack://application:,,,/AssemblyA;Images/books_48.png"
"pack://application:,,,/AssemblyA;/Images/books_48.png"
"pack://application:,,,/Images/books_48.png"
"pack://application:,,,Images/books_48.png"
"Images/books_48.png"
"/Images/books_48.png"

They all give me errors (either "can't find it" or "invalid URI" kind of errors).

Vaccano
  • 78,325
  • 149
  • 468
  • 850
  • Shouldn't it be embedded resource? – Paul Sullivan Jun 15 '12 at 20:42
  • @PaulSullivan - In the comments to this answer (http://stackoverflow.com/a/483891/16241), people seem to be stating that embedded resources are wrong 99% of the time. Something about including the image in the app twice. – Vaccano Jun 15 '12 at 20:52
  • Yeah, it should just be Resource as far as I'm aware. Vaccano - does Assembly B reference Assembly A? Or are they both loaded into another executable... or? – Tim Jun 15 '12 at 20:56

2 Answers2

0

I use my ImageUtilities class to get images in C#. I'll attach the code below..

I ALWAYS set my images to 'Resource' 'Do not copy'. Then I ALWAYS copy all my images into my Properties\Resources.resx file. This can be done in visual studio by expanding your 'Properties' folder that is the first item in your Project folder. Then double click the 'Resources.resx' file and the designer will pop up. At the upper left of this window, click the dropdown and select 'Images'. Then highlight all your image files that are in your project (from the Solution Explorer) and copy/paste them into the window for Resources.resx.

This way, in the code behind, I can access them by typing:

Properties.Resources.ImageName;

That gives you a Bitmap.

I use my ImageUtilities class to convert it to an ImageSource for use with WPF. So if I had an image called 'MyPicture.png', I would make the following call on my ImageUtilities class:

ImageSource source = ImageUtilities.ImageSourceFromResourceKey(
                                  Properties.Resources.MyPicture, "MyPicture");

The reason I pass the text 'MyPicture' is so I can cache the images and not have to create them more than one time per image.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Helpers
{
    public static class ImageUtilities
    {
        [System.Runtime.InteropServices.DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr hObject);
        public static Dictionary<String, ImageSource> _cachedImages = new Dictionary<string, ImageSource>();

        public static ImageSource ImageSourceFromBitmap(Bitmap bitmap)
        {
            if (bitmap == null)
            {
                return ImageSourceFromResourceKey(Properties.Resources.Exit, "Exit");
            }

            try
            {
                IntPtr hBitmap = bitmap.GetHbitmap();
                BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    hBitmap,
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());

                DeleteObject(hBitmap);
                return bitmapSource;
            }
            catch (Exception ex)
            {
                //Error loading image.. Just log it...
                Helpers.Debug(ex.ToString());
            }

            return null;
        }

        public static ImageSource ImageSourceFromResourceKey(Bitmap bitmap, string imageKey)
        {
            if (!_cachedImages.ContainsKey(imageKey))
            {
                _cachedImages[imageKey] = ImageSourceFromBitmap(bitmap);
            }

            return _cachedImages[imageKey];
        }
    }
}
Curtis
  • 5,794
  • 8
  • 50
  • 77
-2

See Nuno Rodriguez's answer to WPF image resources. It explains that the path should be:

"/«Assembly A»;component/«YourPath»/«YourImage.png»"

Community
  • 1
  • 1
Chris Shain
  • 50,833
  • 6
  • 93
  • 125
  • I tried that but since I am doing it in C# (not in XAML), that kind of path returns an "Invalid URI" error (UriFormatException). – Vaccano Jun 18 '12 at 16:08