• Blog
  • Info Support
  • Career
  • Training
  • International Group
  • Info Support
  • Blog
  • Career
  • Training
  • International Group
  • Search
logo InfoSupport
  • Latest blogs
  • Popular blogs
  • Experts
      • Alles
      • Bloggers
      • Speakers
  • Meet us
  • About us
    • nl
    • en
    • .NET
    • Advanced Analytics
    • Agile
    • Akka
    • Alexa
    • Algorithms
    • Api's
    • Architectuur
    • Artificial Intelligence
    • ATDD
    • Augmented Reality
    • AWS
    • Azure
    • Big Data
    • Blockchain
    • Business Intelligence
    • Cloud
    • Code Combat
    • Cognitive Services
    • Communicatie
    • Containers
    • Continuous Delivery
    • CQRS
    • Cyber Security
    • Dapr
    • Data
    • Data & Analystics
    • Data Science
    • Data Warehousing
    • Databricks
    • DevOps
    • Digital Days
    • Docker
    • eHealth
    • Enterprise Architecture
    • Hacking
    • Infrastructure & Hosting
    • Innovatie
    • Integration
    • Internet of Things
    • Java
    • Machine Learning
    • Microservices
    • Microsoft
    • Microsoft Bot Framework
    • Microsoft Data Platform
    • Mobile Development
    • Mutation Testing
    • Open source
    • Pepper
    • Power BI
    • Privacy & Ethiek
    • Python
    • Quality Assistance & Test
    • Quality Assurance & Test
    • Requirements Management
    • Scala
    • Scratch
    • Security
    • SharePoint
    • Software Architecture
    • Software development
    • Software Factory
    • SQL Server
    • SSL
    • Start-up
    • Startup thinking
    • Stryker
    • Test Quality
    • Testing
    • TLS
    • TypeScript
    • Various
    • Web Development
    • Web-scale IT
    • Xamarin
    • Alles
    • Bloggers
    • Speakers
Home » GMImagePicker ported to Xamarin.iOS
  • GMImagePicker ported to Xamarin.iOS

    • By Roy Cornelissen
    • Various 6 years ago
    • Various 0 comments
    • Various Various
    GMImagePicker ported to Xamarin.iOS

    TL;DR
    I ported GMImagePicker to C#. Code here, Nuget here. Happy coding!

    This past week I was working on a Xamarin project where we need support for selecting multiple images and/or taking pictures and uploading them to a backend service. The default UIImagePicker control in iOS is ok but not very versatile. It can take a picture with the camera, or lets you select a single image from your gallery but that’s about it. Furthermore, working with the resulting images is quite cumbersome as you’re working with large UIImage objects in memory. A lot of performance and memory issues can happen if you’re not careful.

    In order to deal with photos and videos more efficiently and in a much richer manner, Apple introduced the PhotoKit API in iOS 8. Mike Bluestein has written a nice introductory post on this API on the Xamarin blog, so I’m not going to repeat this.

    In short, PhotoKit works with the notion of PHAsset objects, which are basically descriptors for media files on the device. There are API’s to query different photo galleries, etcetera. Only once you actually need the image for display or other purposed do you have to retrieve the image using the PHAsset descriptor. Very efficient.

    Many apps, such as the Facebook app, allow users to select multiple images in a user friendly manner, and maybe even add pictures on the go by providing access to the camera while they are browsing their gallery. This is something that we also wanted to add to our app. Luckily, there are some nice open source projects around that implement just that. One of the nicest ones is the GMImagePicker component by Guillermo Muntaner Perelló, which uses the PhotoKit API under the hood. The user experience looks like this:

    gmimagepickerdemo

    That’s slick! You can browse through several collections, and the control is highly customizable, and even contains localized texts for labels, buttons and dialogs. Only, it’s written in Objective-C…

    I had two options: bind the API using Xamarin’s Objective Sharpie or port it verbatim to C#. I chose to port it, mainly to have full control over the inner workings of the control and to not have to pull in a “foreign” language into the project. The port has complete feature parity with the Objective-C version and I tried to iron out as many issues as I could. It seems to be working pretty smoothly in my Xamarin app.

    The code is up on GitHub and you can use the control by either downloading the code and including the .csproj in your project, or install the Nuget package in your Xamarin.iOS app:

    Install-Package GMImagePicker.Xamarin
    

    As I said, the GMImagePicker control is highly customizable. You can change its appearance by specifying colors for different parts of the UI, and you can provide custom titles and confirmation prompts. It’s also possible to filter and limit the types of assets you want the user to select. The whole range of options can be found in the sample app that comes with the control. Here is an overview:

    var picker = new GMImagePickerController {
    Title = "Custom Title",
    CustomDoneButtonTitle = "Finished",
    CustomCancelButtonTitle = "Nope",
    CustomNavigationBarPrompt = "Take a new photo or select an existing one!",
    ColsInPortrait = 3,
    ColsInLandscape = 5,
    MinimumInteritemSpacing = 2.0f,
    DisplaySelectionInfoToolbar = true,
    AllowsMultipleSelection = true,
    ShowCameraButton = true,
    AutoSelectCameraImages = true,
    ModalPresentationStyle = UIModalPresentationStyle.Popover,
    MediaTypes = new [] { PHAssetMediaType.Image },
    // Other customizations to play with:
    //ConfirmSingleSelection = true,
    //ConfirmSingleSelectionPrompt = "Do you want to select the image you have chosen?",
    //PickerBackgroundColor = UIColor.Black,
    //PickerTextColor = UIColor.White,
    //ToolbarBarTintColor = UIColor.DarkGray,
    //ToolbarTextColor = UIColor.White,
    //ToolbarTintColor = UIColor.Red,
    //NavigationBarBackgroundColor = UIColor.Black,
    //NavigationBarTextColor = UIColor.White,
    //NavigationBarTintColor = UIColor.Red,
    //PickerFontName = "Verdana",
    //PickerBoldFontName = "Verdana-Bold",
    //PickerFontNormalSize = 14.0f,
    //PickerFontHeaderSize = 17.0f,
    //PickerStatusBarStyle = UIStatusBarStyle.LightContent,
    //UseCustomFontForNavigationBar = true,
    };
    
    // You can limit which galleries are available to browse through
    picker.CustomSmartCollections = new [] {
    PHAssetCollectionSubtype.SmartAlbumUserLibrary,
    PHAssetCollectionSubtype.AlbumRegular
    };
    
    // Event handling
    picker.FinishedPickingAssets += Picker_FinishedPickingAssets;
    picker.Canceled += Picker_Canceled;
    
    // Other events to implement in order to influence selection behavior:
    // Set EventArgs::Cancel flag to true in order to prevent the action from happening
    picker.ShouldDeselectAsset += (s, e) => { /* allow deselection of (mandatory) assets */ };
    picker.ShouldEnableAsset += (s, e) => { /* determine if a specific asset should be enabled */ };
    picker.ShouldHighlightAsset += (s, e) => { /* determine if a specific asset should be highlighted */ };
    picker.ShouldShowAsset += (s, e) => { /* determine if a specific asset should be displayed */ };
    picker.ShouldSelectAsset += (s, e) => { /* determine if a specific asset can be selected */ };
    picker.AssetSelected += (s, e) => { /* keep track of individual asset selection */ };
    picker.AssetDeselected += (s, e) => { /* keep track of individual asset de-selection */ };
    
    // The GMImagePicker can be treated as a PopOver as well:
    var popPC = picker.PopoverPresentationController;
    popPC.PermittedArrowDirections = UIPopoverArrowDirection.Any;
    popPC.SourceView = gmImagePickerButton;
    popPC.SourceRect = gmImagePickerButton.Bounds;
    
    await PresentViewControllerAsync(picker, true);
    

    The extensibility is very convenient. For example: if you want to set a maximum to the total size of the images you want to allow the user to select, you can handle the AssetSelected event, keep track of the total size selected, and handle ShouldSelectAsset, to prevent selection if a maximum threshold has been reached. This is exactly what we wanted to have in our app.

    Once the user has finished selecting assets, you can use a PHImageManager to retrieve the actual images in whatever size you like:

    void FinishedPickingAssets (object s, MultiAssetEventArgs e)
    {
      PHImageManager imageManager = new PHImageManager();
    
      foreach (var asset in e.Assets) {
        imagePreview.Image = null;
    
        imageManager.RequestImageForAsset (asset, 
          new CGSize(asset.PixelWidth, asset.PixelHeight), 
          PHImageContentMode.Default, 
          null, 
          (image, info) => {
            // do something with the image (UIImage), e.g. upload to server
            // you can get the JPEG byte[] via image.AsJPEG()
          });
      }
    }
    

    Very nice, and it’s now available for Xamarin.iOS developers as well:)

    photo-1437419764061-2473afe69fc2

    Photo by Andrew Illarionov (https://unsplash.com/photos/-WW8jBak7bo)

    Many thanks to Guillermo for letting me port his excellent code and publish it. I’d love to hear your feedback on the code and would love to see your PR’s for improvements.

    Share this

View profile

IT Training at Info Support

Which training fits you?

Consultancy

Consultancy

Related blogs

  • Video Conferencing en OBS Studio koppelen: online prese…

    Video Conferencing en OBS Studio koppelen: online prese… Maaike Brouwer - 1 year ago

  • Verantwoordelijkheid pakken in jouw eigen persoonlijke …

    Verantwoordelijkheid pakken in jouw eigen persoonlijke … Stephan Versteegh - 1 year ago

  • Tips voor als je gaat afstuderen

    Tips voor als je gaat afstuderen Bart Renders - 2 years ago

Related downloads

  • Beslisboom voor een rechtmatig ‘kopietje productie’

  • Klantreferentie: Remmicom zet wetgeving om in intellige…

  • Klantreferentie RDW: Samenwerken voor veilig en vertrou…

  • Klantreferentie BeFrank: Strategische IT voor een innov…

  • Wie durft te experimenteren met data in de zorg?

Related videos

  • mijnverzekeringenopeenrij.nl

    mijnverzekeringenopeenrij.nl

  • Winnaar | Innovation Projects 2017

    Winnaar | Innovation Projects 2017

  • Explore | Info Support & HAN & Poliskluis

    Explore | Info Support & HAN & Poliskluis

  • LifeApps bij HagaZiekenhuis

    LifeApps bij HagaZiekenhuis

  • Info Support | Bedrijfsfilm

    Info Support | Bedrijfsfilm

Nieuwsbrief

* verplichte velden

Contact

  • Head office NL
  • Kruisboog 42
  • 3905 TG Veenendaal
  • T +31 318 552020
  • Call
  • Mail
  • Directions
  • Head office BE
  • Generaal De Wittelaan 17
  • bus 30 2800 Mechelen
  • T +32 15 286370
  • Call
  • Mail
  • Directions

Follow us

  • Twitter
  • Facebook
  • Linkedin
  • Youtube

Newsletter

Sign in

Extra

  • Media Library
  • Disclaimer
  • Algemene voorwaarden
  • ISHBS Webmail
  • Extranet
Beheer cookie toestemming
Deze website maakt gebruik van Functionele en Analytische cookies voor website optimalisatie en statistieken.
Functioneel
Altijd actief
De technische opslag of toegang is strikt noodzakelijk voor het legitieme doel het gebruik mogelijk te maken van een specifieke dienst waarom de abonnee of gebruiker uitdrukkelijk heeft gevraagd, of met als enig doel de uitvoering van de transmissie van een communicatie over een elektronisch communicatienetwerk.
Voorkeuren
De technische opslag of toegang is noodzakelijk voor het legitieme doel voorkeuren op te slaan die niet door de abonnee of gebruiker zijn aangevraagd.
Statistieken
De technische opslag of toegang die uitsluitend voor statistische doeleinden wordt gebruikt. De technische opslag of toegang die uitsluitend wordt gebruikt voor anonieme statistische doeleinden. Zonder dagvaarding, vrijwillige naleving door uw Internet Service Provider, of aanvullende gegevens van een derde partij, kan informatie die alleen voor dit doel wordt opgeslagen of opgehaald gewoonlijk niet worden gebruikt om je te identificeren.
Marketing
De technische opslag of toegang is nodig om gebruikersprofielen op te stellen voor het verzenden van reclame, of om de gebruiker op een website of over verschillende websites te volgen voor soortgelijke marketingdoeleinden.
Beheer opties Beheer diensten Beheer leveranciers Lees meer over deze doeleinden
Voorkeuren
{title} {title} {title}