{"id":4234,"date":"2014-09-25T08:59:47","date_gmt":"2014-09-25T07:59:47","guid":{"rendered":"http:\/\/www.thetawelle.de\/?p=4234"},"modified":"2014-10-01T21:24:55","modified_gmt":"2014-10-01T20:24:55","slug":"using-uiimage-pdf-category-for-x-resolution-independence-and-ever-increasing-apple-idevice-size-fragmentation","status":"publish","type":"post","link":"https:\/\/www.thetawelle.de\/?p=4234","title":{"rendered":"Using UIImage-PDF category for @#x resolution independence coping with ever increasing Apple iDevice Size Fragmentation"},"content":{"rendered":"<p>Since <strong>iOS 8<\/strong> revealed <strong>YADS (Yet another device size)<\/strong>, things start to become too fragmented and way to complicated to optimize the display of your app on all those devices down to the pixel. I mean there never was a pixel, only a point and subpixel antialiasing, but up until <strong>@2x<\/strong> we were able to optimize for pixel perfect alignments with a little bit of extra effort in Photoshop (or other good tools like Pixelmator).<\/p>\n<h3>The Post-@2x-era<\/h3>\n<p>Since <strong>@3x<\/strong> this time is over. If you have a universal app which needs to work on iPad, iPhone and iPod and on @1x, @2x and @3x, your <strong>matrix<\/strong> looks something like this:<\/p>\n<table border=1 cellpadding=5 cellspacing=0>\n<tr style=\"background-color:lightgray;\">\n<th>&nbsp;<\/th>\n<th>iPhone\/iPod<\/th>\n<th>iPad<\/th>\n<\/tr>\n<tr>\n<th style=\"background-color:lightgray;\">@1x<\/th>\n<td>Picture.png<\/td>\n<td>PicturePad.png<\/td>\n<\/tr>\n<tr>\n<th style=\"background-color:lightgray;\">@2x<\/th>\n<td>Picture@2x.png<\/td>\n<td>PicturePad@2x.png<\/td>\n<\/tr>\n<tr>\n<th style=\"background-color:lightgray;\">@3x<\/th>\n<td>Picture@3x.png<\/td>\n<td><b>Who knows what`s next?<\/b><\/td>\n<\/tr>\n<\/table>\n<p>If your app goes the extra mile on perfect UXP with the display of your image assets you will also take portrait and landscape orientation into account. This means the following:<\/p>\n<table border=1 cellpadding=5 cellspacing=0>\n<tr style=\"background-color:lightgray;\">\n<th>&nbsp;<\/th>\n<th>iPhone\/iPod<\/th>\n<th>iPad<\/th>\n<\/tr>\n<tr>\n<th style=\"background-color:lightgray;\">Portrait@1x<\/th>\n<td>Picture.png<\/td>\n<td>PicturePad.png<\/td>\n<\/tr>\n<tr>\n<th style=\"background-color:lightgray;\">Landscape@1x<\/th>\n<td>PictureLandscape.png<\/td>\n<td>PicturePadLandscape.png<\/td>\n<\/tr>\n<tr>\n<th style=\"background-color:lightgray;\">Portrait@2x<\/th>\n<td>Picture@2x.png<\/td>\n<td>PicturePad@2x.png<\/td>\n<\/tr>\n<tr>\n<th style=\"background-color:lightgray;\">Landscape@2x<\/th>\n<td>PictureLandscape@2x.png<\/td>\n<td>PicturePadLandscape@2x.png<\/td>\n<\/tr>\n<tr>\n<th style=\"background-color:lightgray;\">Portrait@3x<\/th>\n<td>Picture@3x.png<\/td>\n<td><b>Who knows what`s next?<\/b><\/td>\n<\/tr>\n<tr>\n<th style=\"background-color:lightgray;\">Landscape@3x<\/th>\n<td>PictureLandscape@3x.png<\/td>\n<td><b>Even in Landscpe?<\/b><\/td>\n<\/tr>\n<\/table>\n<p>If you have 9 image assets you want to display (say some simple icons), this will amount to <strong>9 x 10 = 90<\/strong> image assets to add. Repeat my words, that is <strong>ninety assets<\/strong> you need to provide.<\/p>\n<h3>The power of 10<\/h3>\n<p>This was way too much for me. Since I am independent developer, I simply cannot afford ill-sized amount of workload. So why not go back to 9 image assets from the 90 assets you usually need to craft?<\/p>\n<p>And that is what I did. I just vectorized all those image icons which were very important for the main screen in my app. That took some time, but from now on I simply do not care anymore about Apple&#8217;s next plans to release the oversized <strong>iPhone Plus Plus<\/strong> or the <strong>iPhone Super Plus<\/strong> or the <strong>iPad Air Hyper Retina<\/strong> or the <strong>iPod Hexagonal<\/strong>. Even iOS 9 with frosted glass effect for text and vibrancy effect for the device home button&#8230; I DON&#8217;T CARE.<\/p>\n<p>I just use mindbrix <a href=\"https:\/\/github.com\/mindbrix\/UIImage-PDF\" title=\"iOS Objective-C Category\">UIImage-PDF<\/a>, a category which enables to create UIImages from PDF-files containing scalable vector content (Kudos to <a href=\"http:\/\/www.cocoanetics.com\/2010\/06\/rendering-pdf-is-easier-than-you-thought\/\">cocoanetics<\/a>). This category allows you to switch your assets from <strong>.png<\/strong> to <strong>.pdf<\/strong> in no time and saves you megabytes in your binary bundle.<\/p>\n<h3>Results of using PDF<\/h3>\n<p>I have an app on the AppStore called <strong><a href=\"https:\/\/itunes.apple.com\/us\/app\/seewetter-pro\/id384086202?mt=8\">Sea Weather Pro<\/a><\/strong> which actually needs 9 icons and uses them to create a nice rendered main screen menu with large tap targets and some kind of &#8222;plates&#8220; which have a light gradient and some nearly invisible borders. These plates need to be rendered differently in different sizes and with different icon sizes and for different screen scales on each and every device in portrait and landscape.<\/p>\n<p>The Portrait screen looks like this now (click to see full size):<br \/>\n<a href=\"\/wp-upload\/pdf_portrait.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4253\"  src=\"\/wp-upload\/pdf_portrait_vert_550.png\" alt=\"\" width=\"310\" height=\"550\" class=\"aligncenter size-full wp-image-4253\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/pdf_portrait_vert_550.png 310w, https:\/\/www.thetawelle.de\/wp-upload\/pdf_portrait_vert_550-169x300.png 169w\" sizes=\"auto, (max-width: 310px) 85vw, 310px\" \/><\/a><\/p>\n<p>The Landscape screen looks like this now (click to see full size):<br \/>\n<a href=\"\/wp-upload\/pdf_landscape.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4249\"  src=\"\/wp-upload\/pdf_landscape_550.png\" alt=\"\" width=\"550\" height=\"310\" class=\"aligncenter size-full wp-image-4249\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/pdf_landscape_550.png 550w, https:\/\/www.thetawelle.de\/wp-upload\/pdf_landscape_550-300x169.png 300w\" sizes=\"auto, (max-width: 550px) 85vw, 550px\" \/><\/a><\/p>\n<p>I was able to adjust the landscape size of the icons on these plates to be a little bit smaller, so when the iPhone\/iPod is rotated to the landscape orientation the overall visual impression is lighter than before. This was only possible due to the use of PDF-assets.<\/p>\n<h3>The used resources (png vs. pdf)<\/h3>\n<p>The assets I used were completely different. It was bitmap versus vector data and the vector won by far. The additional flexibility you gain for having every size you want at any time with no more tool involved than UIImage, combined with the time saved editing and slicing bitmap assets is mindblowing.<\/p>\n<p><strong>BUT<\/strong> and this is a real issue, I was at first not able to use a PDF file which actually supports alpha blending or transparency. This is a well known issue because PDF never was meant to be used for something other than printing on paper (which is white\/opaque background by default). So we need to jump through the following loop, if your exported PDF file does not yet kill the <a href=\"http:\/\/indesignsecrets.com\/eliminating-the-white-box-effect.php\">white box<\/a> usually found in such files when <a href=\"http:\/\/www.peachpit.com\/articles\/article.aspx?p=1324260\">exported<\/a>.<\/p>\n<p><strong>Where I used this before:<\/strong><br \/>\n<a href=\"\/wp-upload\/png_resource_navigation@2x.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4256\"  src=\"\/wp-upload\/png_resource_navigation@2x.png\" alt=\"PNG Resource\" width=\"100\" height=\"100\" class=\"aligncenter size-full wp-image-4256\" \/><\/a><\/p>\n<p><strong>I now use this:<\/strong><br \/>\n<a href=\"\/wp-upload\/pdf_resource_navigation.pdf\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4258\"  src=\"\/wp-upload\/pdf_resource_navigation_550.png\" alt=\"PDF Resource\" width=\"550\" height=\"539\" class=\"aligncenter size-full wp-image-4258\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/pdf_resource_navigation_550.png 550w, https:\/\/www.thetawelle.de\/wp-upload\/pdf_resource_navigation_550-300x294.png 300w\" sizes=\"auto, (max-width: 550px) 85vw, 550px\" \/><\/a><\/p>\n<h3>The process in 11 steps (using InkScape in X11 &#038; XQuartz FTW!)<\/h3>\n<p>I was a Photoshop heavy user in the <strong>Ante-@3x-era<\/strong>, so all my resources are still in PSD-files. My vectorization of icons was done in PS. When I started saving the vectorized content as PDF-files I recognized that the PDF files contained always a white box on which the shape was drawn. There was no transparency or alpha blending whatsoever. I tried really every single configuration and colorspace to make this box disappear. <strong>It was not possible!<\/strong> So I tried using <strong><a href=\"http:\/\/www.inkscape.org\/\">InkScape<\/a><\/strong> to fix my problem. Which actually worked.<\/p>\n<p><a href=\"\/wp-upload\/process_inkscape_01.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4263\"  src=\"\/wp-upload\/process_inkscape_01.png\" alt=\"process_inkscape_01\" width=\"550\" height=\"540\" class=\"aligncenter size-full wp-image-4263\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_01.png 550w, https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_01-300x294.png 300w\" sizes=\"auto, (max-width: 550px) 85vw, 550px\" \/><\/a><\/p>\n<p><strong>Step 1<\/strong><br \/>\nImport EPS file you exported from Photoshop. Be careful to clip to the objects bounds\/frame. This ensures you keep the aspect ratio and spacing in the document.<br \/>\n<a href=\"\/wp-upload\/process_inkscape_02.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4262\"  src=\"\/wp-upload\/process_inkscape_02.png\" alt=\"process_inkscape_02\" width=\"550\" height=\"321\" class=\"aligncenter size-full wp-image-4262\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_02.png 550w, https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_02-300x175.png 300w\" sizes=\"auto, (max-width: 550px) 85vw, 550px\" \/><\/a><\/p>\n<p><strong>Step 2<\/strong><br \/>\nNow you see your icon, but you also have a white background, which should be transparent (alpha = 0).<br \/>\n<a href=\"\/wp-upload\/process_inkscape_03.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4264\"  src=\"\/wp-upload\/process_inkscape_03.png\" alt=\"process_inkscape_03\" width=\"550\" height=\"432\" class=\"aligncenter size-full wp-image-4264\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_03.png 550w, https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_03-300x235.png 300w\" sizes=\"auto, (max-width: 550px) 85vw, 550px\" \/><\/a><\/p>\n<p><strong>Step 3<\/strong><br \/>\nAdd a layer to the image, below the existing layer containing your whole shape.<br \/>\n<a href=\"\/wp-upload\/process_inkscape_04.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4265\"  src=\"\/wp-upload\/process_inkscape_04.png\" alt=\"process_inkscape_04\" width=\"550\" height=\"429\" class=\"aligncenter size-full wp-image-4265\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_04.png 550w, https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_04-300x233.png 300w\" sizes=\"auto, (max-width: 550px) 85vw, 550px\" \/><\/a><\/p>\n<p><strong>Step 4<\/strong><br \/>\nDraw a color filled rectangle on that new layer behind the vector shape you imported.<br \/>\n<a href=\"\/wp-upload\/process_inkscape_05.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4266\"  src=\"\/wp-upload\/process_inkscape_05.png\" alt=\"process_inkscape_05\" width=\"550\" height=\"429\" class=\"aligncenter size-full wp-image-4266\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_05.png 550w, https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_05-300x233.png 300w\" sizes=\"auto, (max-width: 550px) 85vw, 550px\" \/><\/a><\/p>\n<p><strong>Step 5<\/strong><br \/>\nChange to the layer of the vector shape. Choose the selection tool and select the shape. Now choose <strong>ungroup<\/strong> from the menu.<br \/>\n<a href=\"\/wp-upload\/process_inkscape_06.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4267\"  src=\"\/wp-upload\/process_inkscape_06.png\" alt=\"process_inkscape_06\" width=\"445\" height=\"502\" class=\"aligncenter size-full wp-image-4267\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_06.png 445w, https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_06-265x300.png 265w\" sizes=\"auto, (max-width: 445px) 85vw, 445px\" \/><\/a><\/p>\n<p><strong>Step 6<\/strong><br \/>\nNow select the white background box. And press the delete button&#8230;<br \/>\n<a href=\"\/wp-upload\/process_inkscape_07.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4268\"  src=\"\/wp-upload\/process_inkscape_07.png\" alt=\"process_inkscape_07\" width=\"550\" height=\"429\" class=\"aligncenter size-full wp-image-4268\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_07.png 550w, https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_07-300x233.png 300w\" sizes=\"auto, (max-width: 550px) 85vw, 550px\" \/><\/a><\/p>\n<p><strong>Step 7<\/strong><br \/>\nAfter the deletion you now have the single shape without a white box. Select the layer containing the colored rectangle&#8230;<br \/>\n<a href=\"\/wp-upload\/process_inkscape_08.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4269\"  src=\"\/wp-upload\/process_inkscape_08.png\" alt=\"process_inkscape_08\" width=\"550\" height=\"429\" class=\"aligncenter size-full wp-image-4269\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_08.png 550w, https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_08-300x233.png 300w\" sizes=\"auto, (max-width: 550px) 85vw, 550px\" \/><\/a><\/p>\n<p><strong>Step 8<\/strong><br \/>\n&#8230;delete\/remove this layer.<br \/>\n<a href=\"\/wp-upload\/process_inkscape_09.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4270\"  src=\"\/wp-upload\/process_inkscape_09.png\" alt=\"process_inkscape_09\" width=\"550\" height=\"429\" class=\"aligncenter size-full wp-image-4270\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_09.png 550w, https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_09-300x233.png 300w\" sizes=\"auto, (max-width: 550px) 85vw, 550px\" \/><\/a><\/p>\n<p><strong>Step 9<\/strong><br \/>\nNow go to file menu and choose <strong>print<\/strong>&#8230;<br \/>\n<a href=\"\/wp-upload\/process_inkscape_10.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4271\"  src=\"\/wp-upload\/process_inkscape_10.png\" alt=\"process_inkscape_10\" width=\"373\" height=\"397\" class=\"aligncenter size-full wp-image-4271\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_10.png 373w, https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_10-281x300.png 281w\" sizes=\"auto, (max-width: 373px) 85vw, 373px\" \/><\/a><\/p>\n<p><strong>Step 10<\/strong><br \/>\nChoose <strong>&#8222;Print as File&#8220;<\/strong> and give a meaningful name to it.<br \/>\n<a href=\"\/wp-upload\/process_inkscape_11.png\"><img loading=\"lazy\" decoding=\"async\" data-id=\"4272\"  src=\"\/wp-upload\/process_inkscape_11.png\" alt=\"process_inkscape_11\" width=\"550\" height=\"429\" class=\"aligncenter size-full wp-image-4272\" srcset=\"https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_11.png 550w, https:\/\/www.thetawelle.de\/wp-upload\/process_inkscape_11-300x233.png 300w\" sizes=\"auto, (max-width: 550px) 85vw, 550px\" \/><\/a><\/p>\n<p><strong>Step 11<\/strong><br \/>\nYou now have a pdf image that is way smaller than the EPS file or PDF file Photoshop spit out. And this one is able to be rendered with transparency\/alpha blending.<\/p>\n<p><small><strong>Why do I blog this?<\/strong> Because I am fed up with Apple&#8217;s neckbreaking pace of dropping new iOS releases and iDevice sizes. I need to come up with solutions Apple did not provide to make all those transitions cost efficient.<\/p>\n<p>There is no other way to provide app updates than reducing the amount of work on this hell of fragmentation which now was introduced by iOS 8. Even the category class I linked to above is not yet fully ready to be used in iOS 8. Check out my <a href=\"https:\/\/github.com\/trailblazr\/UIImage-PDF\">forked one<\/a> which fixes several issues with caching and the correct scale values.<\/p>\n<p>I hope I can help other independent developers. And I dare Apple to slow down their amount of OS iterations dropped on developers and instead spend a whole year in just improving and cleaning up the mess they left behind after this power play on fragmentation and design changes. Apple please start thinking about usefulness and simplicity again and CONSOLIDATE. And please show some empathy towards developers (aka your ecosystem), or you will soon have messy, ugly and buggy apps all over the place or even worse are left with only OpenGL non-UIKit-using apps like games. <strong>You will end up with a GameStore instead of an AppStore if you continue going down this road.<\/strong> It&#8217;s the developers in the first place which take care of bugfree and perfectly working apps and not your review team. You simply cannot replace developers with reviewers. <strong>And the next time something isn&#8217;t yet ready to ship &#8211; like iOS 8.0? Don&#8217;t ship it! It&#8217;s that simple.<\/strong><\/small><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Since iOS 8 revealed YADS (Yet another device size), things start to become too fragmented and way to complicated to optimize the display of your app on all those devices down to the pixel. I mean there never was a pixel, only a point and subpixel antialiasing, but up until @2x we were able to &hellip; <a href=\"https:\/\/www.thetawelle.de\/?p=4234\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eUsing UIImage-PDF category for @#x resolution independence coping with ever increasing Apple iDevice Size Fragmentation\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,17,88,67,95,59],"tags":[],"class_list":["post-4234","post","type-post","status-publish","format-standard","hentry","category-advocatus-diaboli","category-best-practice","category-coding","category-english","category-hack","category-iphone"],"_links":{"self":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/posts\/4234","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4234"}],"version-history":[{"count":0,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=\/wp\/v2\/posts\/4234\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4234"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4234"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.thetawelle.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4234"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}