27

It has been 4 years since this question has been answered with this blog post.

Is there a standard way to create a UIImage with an image from a URL? Something like:

UIImage image = UIImage.FromFile("http://foo.com/bar.jpg");

I feel like I'm probably missing something really simple.

Community
  • 1
  • 1
Jason Hartley
  • 2,459
  • 1
  • 31
  • 40

5 Answers5

58

Not a one-liner, but with very few lines you can roll your own. E.g.

static UIImage FromUrl (string uri)
{
    using (var url = new NSUrl (uri))
    using (var data = NSData.FromUrl (url))
        return UIImage.LoadFromData (data);
}

The calls, including the one from UIImage, are thread-safe.

poupou
  • 43,413
  • 6
  • 77
  • 174
  • When I try this with a url such as https://www.google.ca/images/srpr/logo11w.png I get "Could not initialize an instance of the type 'MonoTouch.Foundation.NSUrl': the native 'initWithString:' method returned nil." Any idea why that happens? – user2320724 Feb 20 '14 at 02:14
  • `NSUrl` will throw (return `nil` in ObjC) then the provided URL is invalid (not RFC 2396 compliant). See Apple's documentation @ https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/Reference/Reference.html#//apple_ref/occ/instm/NSURL/initWithString: – poupou Feb 20 '14 at 04:21
28

With new await/async support you can do:

public async Task<UIImage> LoadImage (string imageUrl)
        {
            var httpClient = new HttpClient();

            Task<byte[]> contentsTask = httpClient.GetByteArrayAsync (imageUrl);

            // await! control returns to the caller and the task continues to run on another thread
            var contents = await contentsTask;

            // load from bytes
            return UIImage.LoadFromData (NSData.FromArray (contents));
        }

and you call this with:

someYourUIImageObjectOnUI.Image = await this.LoadImage ("some image url");
Pavel Sich
  • 1,299
  • 10
  • 10
5

You want to be sure that you load the image async so that you do not block your UI thread. MonoTouch.Dialog includes an ImageLoader (see sec 5.3) class that you could use.

There are also a couple of variations of UrlImageStore out there to help with async loading images.

Finally, if you want to do it manually, there is a Xamarin Recipe you can use.

Jason
  • 86,222
  • 15
  • 131
  • 146
1

I tried the above, it looks like a great idea, but I get: Cannot implicitly convert type System.Threading.Tasks.Task<MonoTouch.UIKit.UIImage>' toMonotouch.UIKit.UIImage'

[found a solution] The problem was because the
obj.Image = await this.LoadImage (imageUrl) must also be in a method marked async. Then it works!

Thanks

Scott Emick
  • 125
  • 1
  • 3
  • 12
0

Below code should work,

public static async Task<UIImage> LoadImage(string imageUrl)
{
            var httpClient = new HttpClient();

            var contents = await httpClient.GetByteArrayAsync(imageUrl);
            return UIImage.LoadFromData(NSData.FromArray(contents));
}