<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Instagram – IMG.LY Blog</title><description>Posts tagged Instagram on the IMG.LY blog.</description><link>https://img.ly/blog/tag/instagram/</link><language>en-us</language><image><url>https://img.ly/apple-touch-icon.png</url><title>Instagram – IMG.LY Blog</title><link>https://img.ly/blog/tag/instagram/</link></image><atom:link href="https://img.ly/blog/tag/instagram/rss.xml" rel="self" type="application/rss+xml"/><generator>Astro</generator><lastBuildDate>Fri, 19 Jun 2026 11:26:06 GMT</lastBuildDate><ttl>60</ttl><item><title>How to build Instagram’s Story Editor in a Day</title><link>https://img.ly/blog/how-to-build-instagrams-story-editor-in-a-day-23be9adff9b/</link><guid isPermaLink="true">https://img.ly/blog/how-to-build-instagrams-story-editor-in-a-day-23be9adff9b/</guid><pubDate>Wed, 13 Dec 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A common question we get asked from our customers, is whether they’ll be able to create an entirely different user interface using our &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditor SDK&lt;/a&gt;. The SDK comes with it’s own customizable UI, but customization are of course limited to a certain extent. As our SDK is used in many different use cases and contexts, we like to explore what’s possible with the PhotoEditor SDK and its included components. Here, &lt;strong&gt;we decided to build a UI similar to Instagram’s Stories or Snapchat using our SDK&lt;/strong&gt;. By now, this ‘Story UI’ has become a popular way of quickly designing with different elements (stickers, brush and text) rather than enhancing and styling the image only.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Our default UI vs Story UI&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 800px) 800px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;800&quot; height=&quot;590&quot; src=&quot;https://img.ly/_astro/1-Rv39RvsHUCI4TXKC1rHXZQ_Z1l5n2b.webp&quot; srcset=&quot;/_astro/1-Rv39RvsHUCI4TXKC1rHXZQ_Z2eFP2.webp 640w, /_astro/1-Rv39RvsHUCI4TXKC1rHXZQ_1qqAh8.webp 750w, /_astro/1-Rv39RvsHUCI4TXKC1rHXZQ_Z1l5n2b.webp 800w&quot;&gt;&lt;/p&gt;
&lt;p&gt;So we grabbed our own &lt;a href=&quot;https://img.ly/docs/pesdk/&quot;&gt;docs&lt;/a&gt; and headed out to create a demo in which we recreate the Instagram Stories using components from the PhotoEditor SDK. This article presents our approach by starting with a general overview and then diving into the different view controllers to look at specific implementation details. You can follow along by downloading the accompanying &lt;a href=&quot;https://github.com/imgly/pesdk-blog-instagram-ui&quot;&gt;code&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Our customized Story UI in action.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 290px) 290px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;290&quot; height=&quot;580&quot; src=&quot;https://img.ly/_astro/1-s-ZFgd4EuUcuy_s4MDz2sQ_Z9PmrR.webp&quot; srcset=&quot;/_astro/1-s-ZFgd4EuUcuy_s4MDz2sQ_Z9PmrR.webp 290w&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;architecture-andoverview&quot;&gt;Architecture and Overview&lt;/h2&gt;
&lt;p&gt;Any image editing interface is naturally centered around some sort of canvas or preview. This is where the image with all operations applied is rendered and any changes are shown to the user. All tools add their own interface elements to allow modifications like adding stickers, text or brush strokes to the image. To create such a hierarchy of tools, the &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditor SDK&lt;/a&gt; makes heavy use of an iOS pattern called &lt;em&gt;view controller containment&lt;/em&gt;. The root view controller, an &lt;code&gt;EditViewController&lt;/code&gt; in this case, manages a series of child view controllers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;PhotoEditPreviewController&lt;/code&gt; that handles the internal model and all rendering, as well as the rendering canvas itself&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;TextSpriteEditController&lt;/code&gt; above the &lt;code&gt;PhotoEditPreviewController&lt;/code&gt; that allows selection and manipulation of text sprites&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;StickerSpriteEditController&lt;/code&gt; above the &lt;code&gt;PhotoEditPreviewController&lt;/code&gt;manages selection and manipulation of stickers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://miro.medium.com/max/1024/1*iNnmjNai7mPywoKsgLz-xg.png&quot; alt=&quot;The view hierarchy within the EditViewController. The user facing controls are on the left, the root window is on the right.&quot;&gt;&lt;/p&gt;
&lt;p&gt;The child view controllers may manage additional view controllers themselves, but we only need to manage the topmost objects and wire their interfaces together. This is done within the &lt;code&gt;EditViewController&lt;/code&gt; who is also responsible for presenting the view controllers that implement the different tools, &lt;code&gt;StickerViewController&lt;/code&gt;, &lt;code&gt;BrushViewController&lt;/code&gt; and &lt;code&gt;TextViewController&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;These are mainly responsible for managing the interface and adjusting the model accordingly, while the ‘real’ work is being done in the background by the &lt;code&gt;PhotoEditPreviewController&lt;/code&gt; whenever the model gets updated. Thanks to the SDK, creating our &lt;code&gt;BrushViewController&lt;/code&gt; boils down to creating and wiring a &lt;code&gt;BrushEditController&lt;/code&gt; and adding its view, color and size controls to the &lt;code&gt;BrushViewControllers&lt;/code&gt; view. This creates a fully fledged brush tool with OpenGL rendering, color and brush size adjustments, and great performance in just &lt;strong&gt;89 lines&lt;/strong&gt; of code.&lt;/p&gt;
&lt;h2 id=&quot;editviewcontroller&quot;&gt;EditViewController&lt;/h2&gt;
&lt;p&gt;As described in the previous section, the &lt;code&gt;EditViewController&lt;/code&gt; is the root view controller of our demo application and is responsible for showing a preview, presenting tools and rendering the final output. To do so, we add a &lt;code&gt;PreviewEditViewController&lt;/code&gt; and &lt;code&gt;SpriteEditControllers&lt;/code&gt; to the root view and register the &lt;code&gt;EditViewController&lt;/code&gt; as their delegate. Registering as a delegate, allows the &lt;code&gt;EditViewController&lt;/code&gt; to wire all child view controllers and pass data between them. In order to do so, we just need to return objects of other view controllers or react to model changes. All controllers then use the &lt;code&gt;EditViewController&lt;/code&gt; to ask for objects or data they need, for example the current size of the preview view, in order to rearrange interface elements or calculate model updates. As an example, the &lt;code&gt;spriteEditControllerPreviewView(_ spriteEditController:)&lt;/code&gt; method of the &lt;code&gt;SpriteEditControllerDelegate&lt;/code&gt; protocol, asks for the current preview view. All we need to do in our &lt;code&gt;EditViewController&lt;/code&gt; is to get this view from our &lt;code&gt;PreviewEditViewController&lt;/code&gt; and return it:&lt;/p&gt;

&lt;h3 id=&quot;sprite-handling&quot;&gt;Sprite Handling&lt;/h3&gt;
&lt;p&gt;Stickers and text sprites are both sprites, but there are different &lt;code&gt;SpriteEditController&lt;/code&gt; subclasses for each sprite type, because of differing gestures and UI elements. The Instagram UI allows the editing of both sticker and text sprites within a single view, so we need to add both specific controllers, &lt;code&gt;StickerSprite&lt;/code&gt;- and &lt;code&gt;TextSpriteEditController&lt;/code&gt; to our &lt;code&gt;EditViewController&lt;/code&gt; and dynamically enable the appropriate one depending on the currently selected sprite.&lt;/p&gt;
&lt;h2 id=&quot;stickerviewcontroller&quot;&gt;StickerViewController&lt;/h2&gt;
&lt;p&gt;For adding stickers, the Instagram Stories UI offers a single button that presents a grid of all available stickers. Replicating this using the PhotoEditor SDK is easy to do, as the SDK uses a collection view for presentation as well. This collection view is embedded in a &lt;code&gt;StickerSelectionController&lt;/code&gt; which we add to our &lt;code&gt;StickerViewController&lt;/code&gt;. Once again, after registering as the &lt;code&gt;StickerSelectionController&lt;/code&gt;s delegate, we get notified upon selection of any sticker and just need to change the &lt;code&gt;PhotoEditModel&lt;/code&gt; accordingly. To do so, we create a link between the root and the currently presented view controller using the &lt;code&gt;StickerViewControllerDelegate&lt;/code&gt; protocol. Once a sticker has been selected, we create or update a &lt;code&gt;StickerSpriteModel&lt;/code&gt;, pass it to the &lt;code&gt;EditViewController&lt;/code&gt;, which updates the &lt;code&gt;PreviewEditViewController&lt;/code&gt; model:&lt;/p&gt;

&lt;p&gt;This triggers a new rendering pass and the sticker appears on screen. All that’s left to do now is closing the &lt;code&gt;StickerViewController&lt;/code&gt;. Again, we use the delegate pattern to ask the &lt;code&gt;EditViewController&lt;/code&gt; about the &lt;code&gt;referenceSize&lt;/code&gt; that’s needed to calculate the sticker’s normalized size.&lt;/p&gt;
&lt;h2 id=&quot;brushviewcontroller&quot;&gt;BrushViewController&lt;/h2&gt;
&lt;p&gt;This view controller, just as described above, is just a wrapper around the &lt;code&gt;BrushEditController&lt;/code&gt; that adds a color and size selection. Once again, all interaction is handled through delegates and upon closing of the brush tool, the internal model is updated. To support &lt;em&gt;undo&lt;/em&gt;, we need to pass the &lt;code&gt;PreviewEditViewController&lt;/code&gt;’s &lt;code&gt;undoController&lt;/code&gt; and begin a new group, whenever we fire up the tool.&lt;/p&gt;
&lt;h2 id=&quot;textviewcontroller&quot;&gt;TextViewController&lt;/h2&gt;
&lt;p&gt;The text editor Instagram created within their Stories UI is essentially a fullscreen textfield with additional controls for color and size selection. Ignoring the customized design, this can easily be recreated using stock iOS components and essentially only requires listening for keyboard notifications to handle the layout and adjusting the textfield’s properties according to user interactions. Once finished, we create a corresponding &lt;code&gt;TextSpriteModel&lt;/code&gt; that is positioned below the &lt;code&gt;UITextField&lt;/code&gt; and notify the &lt;code&gt;EditViewController&lt;/code&gt; using the delegate. After dismissing the &lt;code&gt;TextViewController&lt;/code&gt; the text rendering is handled by the &lt;code&gt;PhotoEditPreviewController&lt;/code&gt;. When reselecting an existing label, we just prefill the &lt;code&gt;UITextField&lt;/code&gt; with it’s contents and update the model when the label textfield changes. To ensure the &lt;code&gt;UITextField&lt;/code&gt; is the only place the text is currently visible, we hide the &lt;code&gt;spriteView&lt;/code&gt; we previously selected and show it again, once editing has finished.&lt;/p&gt;
&lt;h2 id=&quot;the-result&quot;&gt;The Result&lt;/h2&gt;
&lt;p&gt;Recreating the Instagram Stories UI seemed rather challenging at first, but using our &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditor SDK&lt;/a&gt;, it quickly turned into a very rewarding project. Being able to create something like a brush tool without the need to actually implement any drawing or gesture handling is amazing and helped to create a working prototype in no time. Tricky details like sprite transformations, remote loading of stickers or undo management were entirely handled by the SDK and we could completely focus on the interface itself.&lt;/p&gt;
&lt;p&gt;For more details and some actual code, take a look at the &lt;a href=&quot;https://github.com/imgly/pesdk-blog-instagram-ui&quot;&gt;repository&lt;/a&gt;. We documented all tricky parts and you should be able to start your own implementation using the code. Please keep in mind, that the code may target a slightly older PhotoEditor SDK version, so check for a new version before you start your journey.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thanks for reading! To stay in the loop, subscribe to our &lt;a href=&quot;https://photoeditorsdk.us13.list-manage.com/subscribe?u=dc9f652839dbb620d14d6d28d&amp;#x26;id=04a306e4b2&quot;&gt;Newsletter&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Malte</dc:creator><media:content url="https://blog.img.ly/downloaded_images/How-to-build-Instagram-s-Story-Editor-in-a-Day/1-iNnmjNai7mPywoKsgLz-xg.png" medium="image"/><category>iOS</category><category>Swift</category><category>Instagram</category><category>Snapchat</category><category>Mobile App Development</category><category>Tech</category><category>How-To</category><category>Tutorial</category><category>Learning</category></item><item><title>The IMG.LY Photo Roll</title><link>https://img.ly/blog/the-img-ly-photo-roll-b91f51dcae29/</link><guid isPermaLink="true">https://img.ly/blog/the-img-ly-photo-roll-b91f51dcae29/</guid><description>On giving back to the community </description><pubDate>Thu, 21 Sep 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After today, we at &lt;a href=&quot;https://img.ly/&quot;&gt;IMG.LY&lt;/a&gt; are going to divert some of our energy to a new endeavour, the img.ly Photo Roll. We feel deeply rooted in the open-source movement and we know that the internet and most of the tools that we use today wouldn’t be nearly the same if it wasn’t for the awesome and creative work of countless people that shared their assets for free. Still today we heavily rely on open-source technology and creative work to give us guidance and inspire us to create new and unseen things.&lt;/p&gt;
&lt;p&gt;Working on our product &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditor SDK&lt;/a&gt; for the last two years gave us a lot of useful and valuable insights about photography and the various possibilities to create exceptional visual content. As some of us are enthusiastic photographers, it only seems logical to join the community of photographers and creative folks that enrich the internet with extraordinary and free content every single day. Since we have always gratefully used the work of other people, we would like to give something back to the community. Therefore, we are going to start sharing pictures we took around the globe via our &lt;a href=&quot;https://unsplash.com/@imgly/&quot;&gt;Unsplash&lt;/a&gt; and &lt;a href=&quot;https://www.instagram.com/img.ly/&quot;&gt;Instagram&lt;/a&gt; account. Please feel free to download, use, modify and share them at your will. The photos that we’re going to post over the following weeks and months will also be available in our photo roll that ships with the &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditor SDK&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We certainly hope that you’re going to make use of them. And we’d be happy to hear from you what you created with our pictures, and we’d love to see them in a new guise. After all, their real value only shows if someone is inspired by and can get creative with them.&lt;/p&gt;
&lt;p&gt;Thanks to all the people that contribute to our initiative: &lt;a href=&quot;https://www.instagram.com/buhmi/&quot;&gt;Malte Baumann&lt;/a&gt;, &lt;a href=&quot;http://www.tommi-gutscher.de/&quot;&gt;Tommi Gutscher&lt;/a&gt;, &lt;a href=&quot;https://www.instagram.com/mr.salkin/&quot;&gt;Niklas Priddat&lt;/a&gt;, &lt;a href=&quot;https://www.instagram.com/selcukcems/&quot;&gt;Cem Selcuk&lt;/a&gt; and &lt;a href=&quot;https://www.instagram.com/backslashtwentyone/&quot;&gt;Eray Basar&lt;/a&gt;. Below we have already compiled a few pictures that we are going to post over the next few days. Stay tuned.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;br&gt;
Your friends at &lt;a href=&quot;https://img.ly/&quot;&gt;IMG.LY&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Photo by Malte Baumann&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 600px) 600px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;600&quot; height=&quot;400&quot; src=&quot;https://img.ly/_astro/1-yrbhu_3plpF5nz9_7OVlZA_7QKvd.webp&quot; srcset=&quot;/_astro/1-yrbhu_3plpF5nz9_7OVlZA_7QKvd.webp 600w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://miro.medium.com/max/5456/1*HyHOCppZgqQiJLysOr47CQ.jpeg&quot; alt=&quot;Photo by Niklas Priddat&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Photo by Eray Basar&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 600px) 600px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;600&quot; height=&quot;900&quot; src=&quot;https://img.ly/_astro/1-RSwiOtWt05pPOcokaU_UjQ_1ibeje.webp&quot; srcset=&quot;/_astro/1-RSwiOtWt05pPOcokaU_UjQ_1ibeje.webp 600w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://miro.medium.com/max/2000/1*VT3hhr9G51rxqf7Y2hH_vw.jpeg&quot; alt=&quot;Photo by Malte Baumann&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Photo by Cem Selcuk&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 800px) 800px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;800&quot; height=&quot;458&quot; src=&quot;https://img.ly/_astro/1-txps3Dfjb-UjLelCwqxbFQ_Zv4TiX.webp&quot; srcset=&quot;/_astro/1-txps3Dfjb-UjLelCwqxbFQ_29d9ig.webp 640w, /_astro/1-txps3Dfjb-UjLelCwqxbFQ_1H6C8z.webp 750w, /_astro/1-txps3Dfjb-UjLelCwqxbFQ_Zv4TiX.webp 800w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Photo by Eray Basar&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 800px) 800px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;800&quot; height=&quot;600&quot; src=&quot;https://img.ly/_astro/1-sWiXrX5jLgeOcgvvRH9lIQ_Z1t84pM.webp&quot; srcset=&quot;/_astro/1-sWiXrX5jLgeOcgvvRH9lIQ_4CaSb.webp 640w, /_astro/1-sWiXrX5jLgeOcgvvRH9lIQ_ZFUc6G.webp 750w, /_astro/1-sWiXrX5jLgeOcgvvRH9lIQ_Z1t84pM.webp 800w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thanks for reading! To stay in the loop, subscribe to our &lt;a href=&quot;https://photoeditorsdk.us13.list-manage.com/subscribe?u=dc9f652839dbb620d14d6d28d&amp;#x26;id=04a306e4b2&quot;&gt;Newsletter&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;</content:encoded><dc:creator>Felix</dc:creator><media:content url="https://blog.img.ly/downloaded_images/The-img-ly-Photo-Roll/1-D_wGv2cXlMJnLp-SfrreNg.png" medium="image"/><category>Instagram</category><category>Unsplash</category><category>Photography</category><category>Stock Photos</category><category>Creativity</category><category>Company</category></item><item><title>Bringing Wide Color to PhotoEditor SDK</title><link>https://img.ly/blog/bringing-wide-color-to-photoeditor-sdk-a6ce8bb19ef7/</link><guid isPermaLink="true">https://img.ly/blog/bringing-wide-color-to-photoeditor-sdk-a6ce8bb19ef7/</guid><pubDate>Tue, 10 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Inspired by &lt;a href=&quot;https://medium.com/@mikekrieger&quot;&gt;Mike Krieger&lt;/a&gt;’s &lt;a href=&quot;https://instagram-engineering.com/bringing-wide-color-to-instagram-5a5481802d7d#.2gjnzpdeb&quot;&gt;great post&lt;/a&gt; on supporting wide color images in Instagram, I decided to challenge myself by introducing the same wide color support into our &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditor SDK&lt;/a&gt; within a day.&lt;/p&gt;
&lt;p&gt;Mike did an excellent job describing everything that is needed to support wide color images so I am not going to reiterate his explanation. Instead, here I’m going to share two findings I made in the process.&lt;/p&gt;
&lt;h2 id=&quot;image-export&quot;&gt;Image Export&lt;/h2&gt;
&lt;p&gt;Mike suggests that in order to preserve the color space while converting an &lt;code&gt;UIImage&lt;/code&gt; into a JPEG, the &lt;code&gt;UIImageJPEGRepresentation(_:_:)&lt;/code&gt; method has to be replaced with the new &lt;code&gt;UIGraphicsImageRenderer.jpegData(withCompressionQuality:actions:)&lt;/code&gt; method. Checking the color profile of the generated JPEG by &lt;code&gt;UIImageJPEGRepresentation(_:)&lt;/code&gt; I noticed that it seemed unnecessary and resulting in more work than needed. To verify this, I started &lt;a href=&quot;https://www.hopperapp.com&quot;&gt;Hopper&lt;/a&gt; and took a look at the internals of the new method. Here’s what it basically does:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It passes &lt;code&gt;actions&lt;/code&gt; to &lt;code&gt;UIGraphicsRenderer.runDrawingActions(_:completionActions:)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It obtains the resulting image using &lt;code&gt;UIGraphicsImageRendererContext.currentImage&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It passes that image to &lt;code&gt;UIImageJPEGRepresentation(_:_:)&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As you can see, it makes use of &lt;code&gt;UIImageJPEGRepresentation(_:_:)&lt;/code&gt; internally too, so there really is no need to go the extra mile. If you are actually doing any drawing within the &lt;code&gt;actions&lt;/code&gt; block using wide color &lt;code&gt;UIColor&lt;/code&gt;s it absolutely makes sense to use Mike’s apoproach. But if you only want to convert an &lt;code&gt;UIImage&lt;/code&gt; into a JPEG image, using the old method is far easier.&lt;/p&gt;
&lt;h2 id=&quot;core-image&quot;&gt;Core Image&lt;/h2&gt;
&lt;p&gt;We are using &lt;code&gt;CIImage&lt;/code&gt;, &lt;code&gt;CIFilter&lt;/code&gt; and &lt;code&gt;CIContext&lt;/code&gt; for most of our processing. In our live preview we use a &lt;code&gt;CIContext&lt;/code&gt; to directly render a &lt;code&gt;CIImage&lt;/code&gt; into a &lt;code&gt;GLKView&lt;/code&gt; and I’ve run into exactly the same problem as Mike has — namely not being able to get that view to be color space-aware. Using the offscreen buffer workaround that he suggested was going to be too much work though and also I didn’t want to sacrifice any performance.&lt;/p&gt;
&lt;p&gt;After doing some research and digging further into the GLKit and Core Image assembly I found a nice solution. It looks like in order to render wide color images into OpenGL, OpenGLES 3 and a &lt;code&gt;GLKViewDrawableColorFormat&lt;/code&gt; (that is currently not defined as an &lt;code&gt;enum&lt;/code&gt; case) has to be used. The following code works like a charm for me:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let api: EAGLRenderingAPI&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let colorFormat: GLKViewDrawableColorFormat&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;if #available(iOS 10.0, *) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  if UIScreen.main.traitCollection.displayGamut == .P3 {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    api = .openGLES3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    colorFormat = GLKViewDrawableColorFormat(rawValue: 10)!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  } else {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    api = .openGLES2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    colorFormat = .RGBA8888&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;} else {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  api = .openGLES2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  colorFormat = .RGBA8888&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let context = EAGLContext(api: api)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;let previewView = GLKView(frame: CGRect.zero, context: context!)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;previewView.delegate = self&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;previewView.drawableColorFormat = colorFormat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code creates a &lt;code&gt;GLKView&lt;/code&gt; that is backed by a &lt;code&gt;CAEAGLLayer&lt;/code&gt; with the following &lt;code&gt;drawableProperties&lt;/code&gt; set:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; &quot;EAGLDrawablePropertyRetained&quot;: 0,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; &quot;EAGLDrawablePropertyColorFormat&quot;: EAGLColorFormatRGBA_XR10_64BPP&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately &lt;code&gt;EAGLColorFormatRGBA_XR10_64BPP&lt;/code&gt; also doesn’t seem to be documented at this point, but my guess is that setting this color format on Instagram’s &lt;code&gt;EAGLView&lt;/code&gt; would also solve their problem of making the view color space-aware.&lt;/p&gt;
&lt;p&gt;Thanks to Core Image we can just switch to OpenGLES 3 without having to do any other modifications to our code. However, I am currently not sure if this is considered a private API use. I would greatly appreciate if anyone could shed some light on this.&lt;/p&gt;
&lt;p&gt;I have not yet been able to test this on any device other than the iPhone 7 Plus, but I will update this post if I run into any problems with future tests.&lt;/p&gt;
&lt;h2 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;Getting an app to support wide color images is definitely worth it and not as difficult as I had imagined. Unfortunately, it currently looks like iOS is still missing (public) support for wide color in some parts of its frameworks. I hope that Apple addresses these problems soon. Nevertheless we’re optimistic that we’ll be able to include wide color image support in the next release of our SDK. Feel free to check out our &lt;a href=&quot;https://apps.apple.com/de/app/img-ly-camera-pro-photo-sharing/id589839231&quot;&gt;demo app&lt;/a&gt; in the App Store which we will update as soon as possible.&lt;/p&gt;</content:encoded><dc:creator>Sascha</dc:creator><media:content url="https://blog.img.ly/2020/03/1-VF6BW_zDoIaklWdM3u98Tw.jpeg" medium="image"/><category>iOS</category><category>Swift</category><category>Instagram</category><category>Wide Color</category><category>Core Image</category><category>Tech</category><category>How-To</category><category>Insights</category></item></channel></rss>