How to use NSImage.ImageNamed()?

MattDwenMattDwen NZMember

I'm trying to use NSImage.ImageNamed() to change the image on a NSImageView, using:

img.Image = NSImage.ImageNamed("Image-128");

but the result is always null. The image itself is in the project in \Resources\Images\Image-128.png. I've tried specifying the complete file name, and complete path, with no luck. I've also tried setting the images build action to 'BundleResource' with no luck.

What's the correct way to go about this?

Cheers :)

Posts

  • MikeCodesDotNetMikeCodesDotNet GBXamarin Team Xamurai

    Hi,

    I can't see anything wrong with the code you have provided, so I put together a quick sample to see if I could reproduce the problem you are having. I couldn't get it to throw a null exception error so I've included a link for you to download the sample and try it yourself.

    https://dropbox.com/s/ab9r3ao4eecmrku/ImageTest.zip

    With the version I've linked to, it would be good to know if you can you reproduce the issue? If not it might be worth sharing your solution (you can do this in private if you wish) and I can investigate whats going wrong.

    All the best,

    Mike

  • MattDwenMattDwen NZMember

    Thanks Michael,
    The solution you linked to worked fine.

    With my solution, while playing around with the xib in Xcode, I noticed the images weren't available in the library in their either. I removed the images from the project, and re-added them, and this time everything worked.

    I'm fairly sure I used the same method (right click on resources, Add File), but I could be wrong.
    I also checked the old .csproj by hand, and the image appears to be referenced correctly, so I don't know!

    Thank you!

  • MattDwenMattDwen NZMember

    Actually, going back to this, I can make it consistently fail if the image is in a sub folder. I'd imagine this is a bug, so I'll file it.

  • MikeCodesDotNetMikeCodesDotNet GBXamarin Team Xamurai

    Hi,

    Can you show me the code you are using with a subfolder as I can't reproduce the issue you are seeing.

    All the best,

    Mike

  • MattDwenMattDwen NZMember

    Hey Mike, been real slack at getting back to you!

    I've created my own demo project at https://dl.dropboxusercontent.com/u/6736646/ImageTest.zip

    Two images, both imported with right click on Resources, Add Files. One straight to Resources one to Resources/Images.

    Only the first image is available to be selected in Xcode when editing the xib.
    Also when setting manually, as I've done in MainWindowController.AwakeFromNib, the reference to the second image in the sub folder is null. I've tried both with and without the folder name when declaring the NSImage.

  • pmhart83pmhart83 USMember ✭✭✭
    edited June 2015

    I am having this same problem and can confirm that images in a Resources subfolder will not work with NSImage.ImageNamed(string name).

    I had a solution which would load the 1x images:

    public static NSImage GetBundleImage(string relativePath) { var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Contents", "Resources", relativePath); return new NSImage(path); }

    In my project, all images have a base and @2x version included, for example: "Images/Category/image.png" and "Images/Category/image@2x.png".

    My guess is with the direct path derived above, it never considers the @2x. It would be really annoying to lose our organizational structure and move all images to the root of the Resources folder assuming NSImage.ImageName(...) does provided the @2x.

    I could detect and code for retina, appending a @2x, but there are times in the code where things are layed out based on the image size and I haven't gotten far enough to see if this size would be @2x or like in iOS know to scale the image down to 1x when using imageObj.Size.Width.

  • ChrisHamonsChrisHamons USXamarin Team Xamurai
    edited June 2015

    Hmm. According to this:

    https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Optimizing/Optimizing.html

        [self setImage:[NSImage imageNamed:@"myPhoto"]];
    

    is supposed to just work.

    Maybe http://stackoverflow.com/questions/12241134/mac-app-not-using-retina-2x-image-files ?

    Also new NSImage (string) is calling initWithContentsOfFile.

    Did you want/mean NSImage.ImageNamed (string)?

  • pmhart83pmhart83 USMember ✭✭✭
    edited June 2015

    @ChrisHamons

    Our current solution is the one in the code above (GetBundleImage) which only shows the 1x version of the image. We are trying to fix it so our @2x images appear with out pixilation.

    The static function NSImage.ImageNamed(string) does return an image ONLY if the image is located directly under the Resources folder. I did not confirm yet that it provides the @2x. This static function is the equivalent of what you posted: [NSImage imageNamed:@myPhoto].

    In Xamarin, using "new NSImage(absPath)" does work but it does not utilize the @2x image.

    Since you did not provide the file extension my guess is that NSImage.ImageNamed will work for retina, but the down side is we have to pollute our Resources folders and lose all organization.

    Edit:

    Confirmed, NSImage.ImageNamed(string) DOES show the retina image but is restricted to root dir Resources.

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    Yeah, it appears we copy all of the resouces in the hierarchy you create via folders into the Foo.App/Contents/Resources folder while Xcode ignores groups (their name for folders) and dumps everything in Resources directly. The NSImage.ImageNamed API expects the image to live in Resources directly

    You'll need to get all of those images in the root of Resources folders if you want that API to work. The easiest way is to put them there in the project. You could also do a post build step to "fix" things if you desired instead.

    We can't necessary change the behavior of Resources folder to flatten images in a hierarchy, as that might break existing code. :(

  • TimothyRisiTimothyRisi USXamarin Team Xamurai

    According to https://bugzilla.xamarin.com/show_bug.cgi?id=18102 it looks like this is intended behavior. [NSImage imageNamed:] from Apple appears to only search the root directory for the image in question.

    So far I haven't gotten any method of initializing the image to work correctly with folders and still get the @2x version, I've only been able to retrieve the 1x version from a folder.

  • GermanGarcesGermanGarces USMember

    This is still happening with VS 7.2.2 (build 11)

    Any thoughts?

  • YuriKuznetsovYuriKuznetsov USMember ✭✭

    I copy my images directly in Resources folder and I write
    img.Image = NSImage.ImageNamed("ImageName.png");

    it is work well for me

Sign In or Register to comment.