<?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>WWDC – IMG.LY Blog</title><description>Posts tagged WWDC on the IMG.LY blog.</description><link>https://img.ly/blog/tag/wwdc/</link><language>en-us</language><image><url>https://img.ly/apple-touch-icon.png</url><title>WWDC – IMG.LY Blog</title><link>https://img.ly/blog/tag/wwdc/</link></image><atom:link href="https://img.ly/blog/tag/wwdc/rss.xml" rel="self" type="application/rss+xml"/><generator>Astro</generator><lastBuildDate>Fri, 19 Jun 2026 11:26:08 GMT</lastBuildDate><ttl>60</ttl><item><title>Almost Getting Sherlocked by Apple’s Core Image Team</title><link>https://img.ly/blog/almost-getting-sherlocked-by-apples-core-image-team-76249c370320/</link><guid isPermaLink="true">https://img.ly/blog/almost-getting-sherlocked-by-apples-core-image-team-76249c370320/</guid><pubDate>Tue, 12 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;During each World Wide Developer Conference keynote, app developers all over the world are fearing their app may &lt;a href=&quot;https://www.urbandictionary.com/define.php?term=sherlocked&quot;&gt;get sherlocked&lt;/a&gt; by Apple. This has happened to flashlight apps when Apple introduced a simple toggle in the control center, to f.lux when Apple added exactly the same functionality to macOS and iOS, in parts to Dropbox with the launch of iCloud Drive and to many other developers. This year there was only one obvious of such things, the Workflow app which was acquired a few month ago and instantly turned into Siri Shortcuts by Apple. So no real ‘sherlocking’. But when we skimmed the newest APIs, release notes and session descriptions after the keynote, we found out that the technology behind our Portrait by img.ly app might have gotten sherlocked by the Core Image team. The reason is perfectly summarized in this tweet:&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;“Portrait Segmentation API&lt;br&gt;&lt;br&gt;A new API for third-party developers allows for the separation of layers in a photo, such as separating the background from the foreground.”&lt;br&gt;&lt;br&gt;Hi &lt;a href=&quot;https://twitter.com/halidecamera?ref_src=twsrc%5Etfw&quot;&gt;@halidecamera&lt;/a&gt;&lt;/p&gt;— Preshit Deorukhkar (@preshit) &lt;a href=&quot;https://twitter.com/preshit/status/1003722022466121730?ref_src=twsrc%5Etfw&quot;&gt;June 4, 2018&lt;/a&gt;&lt;/blockquote&gt;&lt;figcaption&gt;How we found out about the new Portrait Segmentation API.&lt;/figcaption&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Quick spoiler&lt;/em&gt;: While Core Images new API is impressive, our technology is still ahead in terms of general availability, required hardware and cross-platform compatibility. But let’s start from the beginning:&lt;/p&gt;
&lt;p&gt;We started working on automated image segmentation in 2016 and decided to focus on portraits in 2017. After spending most of the year on &lt;a href=&quot;https://img.ly/blog/when-creativity-meets-a-i-f48ee9a3612d/&quot;&gt;building a custom deep learning model&lt;/a&gt;, running hundreds of experiments and tweaking our post processing pipeline, we finally released the Portrait app in fall 2017. The app is able to generate portrait segmentations in real-time and allows the user to take a nice selfie, which is then automatically stylized using the segmentation mask and some post processing. This allows for sophisticated effects and got great reception all over the world. The app even got featured multiple times in many different countries. Recently we started looking into inferring depth, as we wanted to bring depth based features to our &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditor SDK&lt;/a&gt;, but needed support on more iPhone devices, Android and especially required depth data for existing images.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&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;720&quot; src=&quot;https://img.ly/_astro/1-gGBarteLQ3HLyjk_BOWRqg_1P3HFh.webp&quot; srcset=&quot;/_astro/1-gGBarteLQ3HLyjk_BOWRqg_1P3HFh.webp 600w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 400px) 400px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;400&quot; height=&quot;510&quot; src=&quot;https://img.ly/_astro/1-wIEvPF-CwcYYkguN3hKyrQ_3DVOn.webp&quot; srcset=&quot;/_astro/1-wIEvPF-CwcYYkguN3hKyrQ_3DVOn.webp 400w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Stylized selfies created using the Portrait app.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 400px) 400px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;400&quot; height=&quot;533&quot; src=&quot;https://img.ly/_astro/1-SbpOElYlADGGsomoQWo1UQ_Xq8J4.webp&quot; srcset=&quot;/_astro/1-SbpOElYlADGGsomoQWo1UQ_Xq8J4.webp 400w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Reading the tweet above, it looked like Apple just added the Portrait apps core functionality to the Core Image framework, making it available to all developers and users running or targeting iOS 12. A little worried about the new competition, we immediately looked into the docs and eagerly waited for the session on last Thursday to see if we’d soon need to find a new unique way of using technology to empower creativity.&lt;/p&gt;
&lt;p&gt;We found out that all you need to do in order to get a segmentation mask along with your image is toggle the following flags when requesting a photo capture from your &lt;code&gt;AVCapturePhotoOutput&lt;/code&gt;:&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 settings: AVCapturePhotoSettings = AVCapturePhotoSettings()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;settings.isDepthDataDeliveryEnabled = true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;settings.isPortraitEffectsMatteDeliveryEnabled = true&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;After the photo is captured, you’re then able to extract the matte in the &lt;code&gt;didFinishProcessingPhoto&lt;/code&gt; callback. And voila, you now have the captured image, a depth map and the mask separating fore- and background available:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 400px) 400px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;400&quot; height=&quot;533&quot; src=&quot;https://img.ly/_astro/1-wNVP-7aqqOfyDpnWcKEc0w_ZrbWCi.webp&quot; srcset=&quot;/_astro/1-wNVP-7aqqOfyDpnWcKEc0w_ZrbWCi.webp 400w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 400px) 400px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;400&quot; height=&quot;533&quot; src=&quot;https://img.ly/_astro/1-k3bRAeLEIxoZ0otelumcdQ_Z1Vd9sB.webp&quot; srcset=&quot;/_astro/1-k3bRAeLEIxoZ0otelumcdQ_Z1Vd9sB.webp 400w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Input image, depth map and portrait matte generated by Core Image. (Source)&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 400px) 400px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;400&quot; height=&quot;533&quot; src=&quot;https://img.ly/_astro/1-_ti3BobfUiGJmsb8MOkJvQ_Z1FhYlR.webp&quot; srcset=&quot;/_astro/1-_ti3BobfUiGJmsb8MOkJvQ_Z1FhYlR.webp 400w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Of course, we quickly spun up our own models and algorithms and compared the portrait matte, as well as the depth map to Apples results. As there is no way to rerun Apples matting algorithm for an existing image, we took one of Apples samples and compared their mask with results from our model:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 400px) 400px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;400&quot; height=&quot;533&quot; src=&quot;https://img.ly/_astro/1-wNVP-7aqqOfyDpnWcKEc0w_ZrbWCi.webp&quot; srcset=&quot;/_astro/1-wNVP-7aqqOfyDpnWcKEc0w_ZrbWCi.webp 400w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 225px) 225px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;225&quot; height=&quot;299&quot; src=&quot;https://img.ly/_astro/1-Tr1guJROO6OdL0BDhMlJ4g_ZGYUc4.webp&quot; srcset=&quot;/_astro/1-Tr1guJROO6OdL0BDhMlJ4g_ZGYUc4.webp 225w&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Input image, depth map and portrait matte generated by our algorithms and models.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; sizes=&quot;(min-width: 400px) 400px, 100vw&quot; data-astro-image=&quot;constrained&quot; data-astro-image-pos=&quot;center&quot; width=&quot;400&quot; height=&quot;533&quot; src=&quot;https://img.ly/_astro/1-2Vj62Jh6cBafzw0kN1xVuA_2h3Jco.webp&quot; srcset=&quot;/_astro/1-2Vj62Jh6cBafzw0kN1xVuA_2h3Jco.webp 400w&quot;&gt;&lt;/p&gt;
&lt;p&gt;While it may not have been the greatest idea to pick Apples shiny developer example, Apples mask is a little more detailed and for this particular image our model missed parts of the neck on the left. But overall we were still very happy with our results, especially when considering, that everything was generated from the plain image and didn’t require any dedicated hardware like dual cameras or a TrueDepth sensor. We did of course expect a superior depth map from Apple, as we’re clearly lacking data and are still actively working on the depth model used to generate the image above. But Apples depthmap interestingly has some issues around the neck as well, despite their use of a dual camera system. And keep in mind, that our results were all processed on the mobile device, entirely based on the RGB data contained in the image, and could be repeated on an Android phone, older iOS devices and even your browser.&lt;/p&gt;
&lt;p&gt;When we wanted to try more samples, we quickly noticed the major limitations of Apples API: As the portrait matte capture is only available in combination with depth data, it’s limited to the iPhone 7 Plus, 8 Plus and iPhone X. And, most important to us, portrait mattes taken using the front camera are exclusively limited to the iPhone X and it’s TrueDepth sensor array. So for our Portrait app, switching to the new API would require us to ditch our live preview and go iPhone X and iOS 12 only. This was enough to calm our minds and we started thinking deeper about Apples technology:&lt;/p&gt;
&lt;p&gt;While the depth requirement is annoying, it also explains the higher quality of Apples predictions. Our model is trained to solve the individual problems of portrait matting and depth map inference as a whole, but Apple is able to focus on improving the edges, while the ‘rough’ foreground/background segmentation is handled by masking based on the depth of the face detected within the image. We might be able to combine both models as well, but that would make the segmentation model currently used in the Portrait app obsolete and would most certainly kill the real-time functionality.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;A stylized portrait of the sample image, created using our app.&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;1066&quot; src=&quot;https://img.ly/_astro/1-suYaswJDYtDiIFTs3w-aHQ_Z29DuwE.webp&quot; srcset=&quot;/_astro/1-suYaswJDYtDiIFTs3w-aHQ_ZJM4aC.webp 640w, /_astro/1-suYaswJDYtDiIFTs3w-aHQ_Z23jUhb.webp 750w, /_astro/1-suYaswJDYtDiIFTs3w-aHQ_Z29DuwE.webp 800w&quot;&gt;&lt;/p&gt;
&lt;p&gt;Overall, Apples technology is, as almost always, pretty impressive and the portrait matte generation works flawless, but we can now say, that for the use within our app, we reach a good quality with our current algorithms and think that a real-time preview is more important to our users. For our &lt;a href=&quot;https://img.ly/products/photo-sdk/&quot;&gt;PhotoEditor SDK&lt;/a&gt; we’d happily use the high fidelity maps generated by iOS 12, but the hardware requirements are not yet suitable for SDK deployment. Our algorithms on the other hand, neither require a depth map, nor are we limited to processing after the image was captured, but can perform real-time inference on devices as old as the iPhone 6S. And the best of all: Once a TrueDepth camera is more common and everyone is running iOS 12, we can still use the Portrait Segmentation API and enjoy it’s simplicity.&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/2020/03/1-EXAAKrECABcaDEs3BtfzgQ.jpeg" medium="image"/><category>Apple</category><category>WWDC</category><category>Core Image</category><category>iOS</category><category>Software Development</category><category>Tech</category><category>How-To</category><category>Insights</category></item></channel></rss>