Retrieve Embedded Resource Image

I had my first haircut since January this weekend :-)

The reason I had such a long break from that task is that I shaved my head completely in January.
I had been thinking of doing that sometime in my life ever since I was a teenager, but I was always way too scared to actually put it into practice.
In the meantime, three of my four kids already showed me how easy it is, and they all looked good, which reduced the threshold somewhat.
I mentioned it to my son Christopher back in November, and he immediately responded with “well, I have a machine for that, let’s get down to it right away.”
I was not that brave, but when he brought up the topic again in January, I was finally ready for it:

Shaving Jeremy's head

His friend Naomi took pictures of the process and Christopher made an animated GIF from them.

I had associated many things with it, such as letting go, clearing up, connecting to the spiritual, getting lighter, accessing my own embedded resources etc…
It was a good feeling :-)

Anyway, today is the day for

leaving, on a jet plane

(lyrics),
for the

AEC DevCamp

in Boston.

Before moving back to Revit, here is an interesting thing to point out that you should not miss: one of the “rarest of predictable celestial phenomena” is taking place tomorrow, June 5: a

transit of Venus in front of the sun
.

Now let me finally get to the less celestial, not-so-spiritual and rather down-to-earth Revit API item before I pack and go.

Question: Can you please provide some insight and sample code on how to retrieve an image from the resources embedded in a DLL?

I am writing an add-in that creates its own Revit ribbon.

I can access image files stored in separate external files without any problems, but I would like to deploy a single DLL without having to include a folder full of images.

Thank you very much!

Answer: Please take a look at the

String Search ADN Plugin of the Month
.
It demonstrates exactly what you are asking for.

The method that is probably of greatest interest to you is the NewBitmapImage one in the external application implementation class App:


  /// <summary>
  /// Load a new icon bitmap from embedded resources.
  /// For the BitmapImage, make sure you reference 
  /// WindowsBase and PresentationCore, and import 
  /// the System.Windows.Media.Imaging namespace. 
  /// </summary>
  BitmapImage NewBitmapImage(
    Assembly a,
    string imageName )
  {
    // to read from an external file:
    //return new BitmapImage( new Uri(
    //  Path.Combine( _imageFolder, imageName ) ) );
 
    Stream s = a.GetManifestResourceStream(
        _namespace_prefix + imageName );
 
    BitmapImage img = new BitmapImage();
 
    img.BeginInit();
    img.StreamSource = s;
    img.EndInit();
 
    return img;
  }

It is used like this in to populate the push button image data:


  d.Image = NewBitmapImage( exe, "Img1.png" );
  d.LargeImage = NewBitmapImage( exe, "Img2.png" );
  d.ToolTipImage = NewBitmapImage( exe, "Img3.png" );

Obviously the images have to be included in the project files and marked as embedded resources in the Visual Studio IDE, and the path within the project has to match.

All of that is demonstrated by the StringSearch sample.

Actually, since I was working on it recently anyway, here is an
updated version of the source code for Revit 2013,
including the entire Visual Studio solution and add-in manifest.


Comments

7 responses to “Retrieve Embedded Resource Image”

  1. Hi, Jeremy.
    I get image from simple resources (not an embedded)
    At first I’ve created converter from a Bitmap to BitmapImage
    public static class BitmapSourceConverter
    {
    public static BitmapSource ConvertFromImage(Bitmap image)
    {
    return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
    image.GetHbitmap(),
    IntPtr.Zero,
    System.Windows.Int32Rect.Empty,
    BitmapSizeOptions.FromEmptyOptions());
    }
    }
    And usage
    pushButton.LargeImage = BitmapSourceConverter.ConvertFromImage(Resources.buttonImage);
    where buttonImage is the image assembly resource which you can add via assembly properties.
    Here is highlighted code: http://pastebin.com/ZcQYN78v
    I think this code is more obvious and more simple than yours because there is no need to use assembly.
    Hope this information is useful.
    Best regards, Victor.

  2. In the army now…(singing)
    Hi Jeremy,
    Changing an icon at runtime, would allow you to simulate a checkbox.
    One could display some global variables this way.
    The user could set them by just one click.
    Just an idea.
    Cheers,
    Rudolf

  3. Dear Victor,
    Yes, agree, that is nice and clean also.
    Some people prefer embedding the icons in the assembly to avoid having them in separate external files.
    Cheers, Jeremy.

  4. Hi Jeremy,
    is there a way to animate the ToolTipImage of a RibbonItem ?
    It would be great if developers could show their own animated videos, as Revit itself does, e.g. if drawing a wall.
    Some sort of animated gif would do the job.
    Any idea ?
    Cheers,
    Rudolf

  5. Hello, Rudolf.
    I’ll try to answer for Jeremy.
    Yes, it is possible and I’ve found the undocumented way to add your own video to the tool tip.
    There are many interesting classes in the AdWindows.dll assembly and in the UIFramework.dll assemblies which you can find in the Revit program folder.
    There is a RibbonToolTip class in the AdWindows.dll assembly. The class has a property – ExpandedVideo. The next step is to find a class which can contain ToolTip property. This class is Autodesk.Windows.RibbonItem.
    So, the idea is to find the correct RibbonItem in the ribbon control and set RibbonToolTip to it.
    But here there is the trouble. We create a PushButton on a Panel (Application.CreatePanel().AddItem(RevitItem) we get a Autodesk.Revit.UI.RibbonItem. But we need Autodesk.Windows.RibbonItem.
    There are several ways.
    The first one – use RevitControl class and iterate all tabs, panels and buttons and find button by name.
    We can get RevitControl instance using static property RibbonControl UIFramework.RevitRibbonControl class.
    RibbonControl contains exactly Autodesk.Windows.RibbonItem items not a Autodesk.Revit.UI.RibbonItem. It’s look like we need.
    Here is the code: http://pastebin.com/aXZ6u2nL
    But there is a second way. The Autodesk.Revit.UI.RibbonItem class has an internal method getRibbonItem() which returns Autodesk.Windows.RibbonItem. Interesting. Try to use this method. The reflection helps us.
    Here is the code: http://pastebin.com/52hVR61d
    So, after we get a Autodesk.Windows.RibbonItem we can set RibbonToolTip to it.
    For example like here: http://pastebin.com/XtpKjLYq
    PROFIT!!!
    Also there is a third way to get a Autodesk.Windows.RibbonItem. Create a tab, panel and button directly via RevitControl class. But I didn’t find how to set IExtenalCommand to a button.
    RevitToolTip.ExpandedVideo support SWF video. Also I’tried a GIF image. The Gif was shown but didn’t animate. Also I tried to set Internet url. On my computer it doesn’t work. May be it doesn’t work via proxy or may be access is denied on video in the internet. Please try and tell me.
    At the last, the full source code of my test project with video tool tip buttons.
    http://dl.dropbox.com/u/62538318/Revit/VCButtonsWithVideoToolTip.zip
    Hope the information is useful for you.
    P.S. Jeremy, I believe it is also the nice new topic for your blog.
    Best regards, Victor.

  6. Hi Victor,
    thanks for answering my question.
    Some time ago, I played around with AdWindows.dll, too:
    http://thebuildingcoder.typepad.com/blog/2011/02/pimp-my-autocad-or-revit-ribbon.html
    ;-)
    I’m in holiday until next monday, so it will take some time to answer your big post.
    As far as I know, you can change the IExternalCommand that is assigned to a button at runtime.
    I really like it if the discussion in the comments section generates new blog postings.
    It shows that there is a growing community.
    See you, have a nice weekend,
    Rudolf

  7. omer iqbal Avatar
    omer iqbal

    how can i display gif image in picturebox via embedd resouce in wpf

Leave a Reply to Victor ChekalinCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading