Taoffi's blog

prisonniers du temps

Xamarin forms: an image source dilemma

 

As we saw during the first 'inside-look', Xamarin exposes the Image control (or 'View', as you like) with its Source (ImageSource) that can be either a FileImageSource, a StreamImageSource or an UriImageSource.

Most of the samples that talk about how to use Image are delivered with FileImageSource… something like this:

<Image Source="photo.png" />

Or, sometimes:

<Image Source="http://company.com/photo.png" />

Great!... it looks like the Image is quite intelligent to directly know if the source is a FileImageSource or a UriImageSource… mazing work… the guys @Xamarin are quite smart and helpful… right?

Not so fast!

After having some trouble with this (you should expect some in this juvenile environmentJ), I understood something: Many (if not all) samples about Xamarin features are often delivered with the very 'trivial' situation… as they may say: for 'pedagogic' reasons (exactly the same reason we heard in primary/secondary schoolJ)

What if we were 'mature' (if not 'professional') people?... well, apparently, you do it yourself!

In the Image case is also probably accentuated by the fact that the ImageSource is a class whose base is the Element class (which is the grand-grand-parent of the Image class!)

The case

What I had to do with Image was to display an image dynamically generated by a service call. A product image for instance which you can get with an Uri that may look like:

http://mycompany.com/myService.svc?productId=123&thumbnail=1

If you try the somehow trivial cases, you simply put:

<Image Source="http://mycompany.com/myService.svc?productId=123&thumbnail=1" />

That simply 'does not work'! (please don't ask me why J)

Fortunately, we know by other experiences that software is sometimes a craftsmanship process.

I first tried using the StreamImageSource (feeding it with a stream filled up with the bytes coming from the service)… but ended up by asking myself why this object exists (it is not probably totally useless… but it was in my case!)

Image source Binding

As you now know, real life is a little different from schools.

So, as you may imagine: I in fact will not have my Image written like this:

<Image Source="http://mycompany.com/myService.svc?productId=123&thumbnail=1" />

It will rather be written like this:

<Image Source="{Binding ProductImageSource}" />

 

ProductImageSource property in this case was returning a string containing the address for getting the image. Counting on the Image intelligence for translating this address to an UriImageSource. Which did not work.

The solution (that works… and not only on my machine!)

Let us change the ProductImageSource from a string to its meaning: an ImageSource.

 

public ImageSource ProductImageSource 
{ 
    Get {    return GetImageUriSource(ProductImageUrl, 5.0);     } 
}

 

GetImageUriSource, a helper method somewhere (in a static class for instance) can do this work for products or other objects when needed:

public static ImageSourceGetImageUriSource(string strUrl, double cacheDurationMinutes) 
{ 
    if (string.IsNullOrEmpty(strUrl)) 
        return null; 

    // escape the url
    strUrl        = Uri.EscapeUriString(strUrl); 
 

    if(!Uri.IsWellFormedUriString(strUrl, UriKind.RelativeOrAbsolute)) 
        return null; 

    Uri            imgUri        = new Uri(strUrl); 

    return new UriImageSource() 
    { 
        CachingEnabled = true, 
        Uri                 = imgUri, 
        CacheValidity = TimeSpan.FromMinutes(cacheDurationMinutes) 
    }; 
}

 

That works!

Comments are closed