Quick Links

Using embedded images as the image for a Button?

We are using Xamarin.Forms to build the UI for an iOS app and we have just hit a problem with using images on buttons. We divide our UI based on function areas and thus we have separate projects for each functional area. As a result, we hope to contain the graphics for a particular functional area to only within that project. This, unfortunately, means that we can only use embedded resources to retrieve those graphics. However, the Button view doesn't seem to accept an image that comes out from an embedded resource, but rather only an image that is loaded from a file. Has anyone encountered this problem? Besides putting those graphics into the main app project's Resources folder (so they will become part of the bundle), is there any other way to solve this problem?

Thanks.

GW

0

Best Answer

The Button.Image property is of type FileImageSource so it must reference an image locally available in the application.

This helps to produce quality applications because it supports the Retina resolution in iOS (just include the double-res image with @2x suffix) and multiple resolutions on Android (put images with the same name in each drawable-_dpi folder).

Using embedded resources does not allow for this automatic handling of resolutions, and users would notice the blocky, pixellated effect of bad images if Retina and hi-res images are not supported.

5

Answers

The Button.Image property is of type FileImageSource so it must reference an image locally available in the application.

This helps to produce quality applications because it supports the Retina resolution in iOS (just include the double-res image with @2x suffix) and multiple resolutions on Android (put images with the same name in each drawable-_dpi folder).

Using embedded resources does not allow for this automatic handling of resolutions, and users would notice the blocky, pixellated effect of bad images if Retina and hi-res images are not supported.

@CraigDunn said:
The Button.Image property is of type FileImageSource so it must reference an image locally available in the application.

This helps to produce quality applications because it supports the Retina resolution in iOS (just include the double-res image with @2x suffix) and multiple resolutions on Android (put images with the same name in each drawable-_dpi folder).

Using embedded resources does not allow for this automatic handling of resolutions, and users would notice the blocky, pixellated effect of bad images if Retina and hi-res images are not supported.

I'm not convinced as this type precludes the use of iOS asset catalogs which is supposed to help with managing high-quality images. It also precludes the possibility of drawing resolution-independent images at runtime. Thus, the use of 'FileImageSource' actually reduces the use of high-quality images and breaks best-practice for iOS asset management.

@DanielBergquist the quote above is from 2014, and is specifically in response to using images embedded as a .NET resource. I stand by the advantages of using files (including @2x and @3x) over a single embedded resource.

iOS asset catalogs have come a long way in 2.5 years (including Xamarin's support for them). We are currently updating our documentation on using Asset Catalogs with Xamarin.Forms; I hope once that's published that it helps. For Android, I think the drawable- dpi folders are still the best option.

@CraigDunn an even better option in XF would be to have allImage-type objects use the most abstract ImageSource possible everywhere. It's pretty hard to see the design rationale for having most Images use FileImageSource when using ImageSource should also work and allow us to have things like SVGs as icons instead of forcing everyone to use files for everything.

I invite anyone on the XF team to produce a badged ToolbarItem icon to see how awkward and difficult this is with the current setup - and how easy it would be if every image source was an ImageSource instead.

Even better than that, please remove the restrictive internal tags on the useful bits of the Image and ImageSource classes and their derivatives. We have way more image sources than XF has provided for, and it's impossible to plug them into the image source ecosystem while so many bits of it are internal.

Opening up all possible image locations (tabs, toolbars, etc) to image sources that are network dependent opens up a whole other can of worms (when apps are on slow or no network). I think this was the original reason for preferring FileImageSource (also, as I originally said, local files are the simplest way to support Retina and hidpi on iOS and Android respectively).

I already submitted a bug report with essentially this complaint and it was rejected as not being on the roadmap at the time.

I understand your concerns about networks etc. and appreciate the desire to keep XF users safe (as it were). However I think making it impossible to do dangerous things is too restrictive and drastically reduces the usefulness of the framework.

In this particular case, a large amount of the time (i.e. multiple days) we saved by defining our screens once-for-all-platforms was wasted trying (and failing) to find workarounds for something that should really be very simple.

The biggest problem with using local files, is that it is a breach of the license agreement when using stock icons & images - "Where a non web-based application is to be distributed, the graphical media must be compiled into the application binary file or its associated data files, documentation files, or components."

I understand your concerns about networks etc. and appreciate the desire to keep XF users safe (as it were). However I think making it impossible to do dangerous things is too restrictive and drastically reduces the usefulness of the framework.

I'm a little torn on what's ideal (resources shipped with the PCL or local files). But, I can say for certain that if you are going to add the option to ship with the PCL, then the feature as it's implemented is inconsistent and justified by questionable reasoning.

I would ask the Xamarin team, what kind of developers you want to focus on for Forms. Do you want a community of mostly junior indie devs who need to be kept "safe" from themselves? Or do you want to provide a framework that is flexible and easily considered by enterprise teams?

Honestly @CraigDunn , I don't appreciate being kept "safe" at all and would prefer flexibility. Feedback of a career .NET Engineer for what it's worth.

I just ran up against this tonight trying to set up a simple button with an image. I think the there is a base scenario here that Xamarin is missing: Image handling in general.

Obviously images are handled differently with strange rules on each platform. If Xamarin is going to be a true cross-platform solution then, it stands to reason that abstract the way an app developer thinks about handling images. (Unity does this pretty well, and MonoGame takes a stab at it with their content pipeline tool.) Having to manage different sets of images for every platform it an exercise in frustration. I get there are special cases, but at least make the 90% case trivial and the 10% cases possible.

What I want: I'd like to be able to put images in my shared code project and just have them work. I assume there will be some intermediate file generation to make this happen, so give me a window into that for times I need to make specific tweaks. (And please also give me detailed error messages when Xamarin can't find images.)