[Rails] Mask an image using ImageMagick, Paperclip and S3

A project I’m currently working on requires image masking. I had already developed the site with plans to deploy to Heroku using Paperclip for image attachments using Amazon S3 for storage (you can read how I set that up here). I scoured the web for existing tutorials and documentation but found little that was relevant to my situation. My first inclination was to write a post-process method – grab the image, mask it and write it back to S3 which proved to be a dead-end (you can see the problem I ran into here – granted it’s possible you could still go that route). After a bit of Googling I ended up using a processor. Here’s what I did (I must confess the “boilerplate” code for the processor was some I found, unfortunately I did not keep the link – if you recognize it please let me know!):

In my model:

  has_attached_file :image,
  :styles =>{
    :main_feature => {:geometry => "1020x470", :processors => [:masker] },
    :large => "1020x470",
    :event_page => "460x212", 
    :top_feature => "345x159",
    :smallest => "229x131"#,
  },
  :storage => :s3,
  :s3_credentials => "#{Rails.root}/config/s3.yml",
  :path => ":attachment/:id/:style.:extension",
  :url => "/:id/:style/:basename.:extension",
  :bucket => "yo-bucket-name"

Note line 3, where I’ve added a processor called “masker”. I created a folder called ‘paperclip_processors’ inside my lib directory and created masker.rb. In that same folder I included the png of my mask (mine is simply called mask.png). I’m using an alpha mask. In masker.rb I placed the following code:

module Paperclip
  class Masker < Processor
    def initialize file, options = {}, attachment = nil
      super
      @format = File.extname(@file.path)
      @basename = File.basename(@file.path, @format)
    end

     def make  
          
      src = @file
      dst = Tempfile.new([@basename, @format])
      dst.binmode

      begin
        parameters = []
        
        parameters << ':source'
        parameters << ':mask'
        parameters << '-alpha'
        parameters << 'on'
        parameters << '-compose'
        parameters << 'CopyOpacity'
        parameters << '-composite'
        parameters << ':dest'

        parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")

        mask_path = File.expand_path('lib/paperclip_processors/mask.png')
        success = Paperclip.run("convert", parameters, :source => "#{File.expand_path(src.path)}[0]", :mask => "#{mask_path}[0]", :dest => File.expand_path(dst.path))
      


       rescue PaperclipCommandLineError => e
         raise PaperclipError, "There was an error during the mask for #{@basename}" if @whiny
       end

       dst
     end

  end
end

Lines 18-25 show the arguments we’ll be using to interface with ImageMagick (the documentation for this is found here). Basically we’re inputting the source and mask, turning the alpha flag on, using the compose method with CopyOpacity to copy the opacity of the mask to the final composite (masked) image and finally the destination. Now when an image is added to my model, a new image is sized and created – best of all, it works on Heroku!

Android Newbie: java.net.UnknownHostException

I’ve been toying with Android a little lately. Today I am working with the Twitter API and got this error:

11-08 15:05:29.461: W/System.err(376): java.net.UnknownHostException: search.twitter.com

You could get this error from any web request. The fix?

Put this line in your AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />

iOS 6 UIRefreshControl – Pull To Refresh Like Mail App

viewDidLoad:

self.refreshControl = [[UIRefreshControl alloc] init];    
[self.refreshControl addTarget:self action:@selector(refreshView:) forControlEvents:UIControlEventValueChanged];

Refresh:

- (void)refreshView:(UIRefreshControl *)sender {
    //Refresh...
    NSLog(@"Refresh");
    
    [sender endRefreshing];
}

Source: http://stackoverflow.com/questions/12607015/uirefreshcontrol-ios-6-xcode

iPhone 5 Design Resource Roundup

It’s not even out yet but there are some great resources available for creating iPhone 5 mock ups. Which is your favorite?

Angled Mockup

Constantinos Demetriadis

[Black]

iPhone 5 Photoshop Action

Simon Lord

[Black / White]

iPhone 5 PSD

Carter Digital
[Black / White]

iPhone 5 Template PSD

Mark Bauer

[Black]

iPhone 5 PSD

Legwork Studio

[Black]

iPhone 5 Mockups PSD (Vector)

Tony Thomas

[Black / White]

iPhone 5 PSD (Vector)

Pixeden

[Black]

Extract (uncrush) Images from an iOS App

Often I’ll see an app incorporate a new UI implementation that really impresses me. Still being a learner, I always wonder how these elements are coded or put together — is it an image trick? Maybe a CGGradientLayer? How are they able to achieve so much speed? It’s times like these that it helps to get a small peek under the hood. Like Mac apps, iOS apps are bundled together basically as a zip file — you can actually change the IPA extension to ZIP and unarchive the app very easily. The limitation here is Xcode compresses (or ‘crushes’) the png’s used in an app to keep the file size down. Luckily, since iOS 3.2, the command line tool that compressed these images included the added functionality of decompressing them. Peter Boctor (of iDevRecipes) wrote a Ruby script called App Crush that would uncrush the png files (with instructions here) but it hasn’t been updated in about a year. Since then, Apple has changed how Xcode is deployed (through the App Store these days) and the location in which they put it. It’s very easy to update the Ruby script to find the new Xcode and several have. I wanted to make it just a tad easier and created an Applescript Droplet that allows you to drag the IPA onto it and uncrushes the png files. You can download it here. I’ve also made this version’s source available here. This is my first attempt at an AppleScript Droplet (which seems like a dying tech) so if you see something that could be done better, let me know!

Usage instructions:

  1. If you don’t know the location of the IPA (app) you’d like to uncrush, open iTunes and click the apps tab, right click on the app you’d like and click “Reveal in Finder”
  2. Drag IPA onto the App Uncrusher
  3. It’ll take up to a few minutes to finish and you’ll have a folder called “APPNAME images” on your desktop that should be full of pngs.

Be ethical with this. Don’t steal another app’s images and call them your own.

Automagically: Easy Splash Screen (Default.png)

In my recent post about reducing load time for iOS apps, I discussed the importance of a proper Default.png. In the past I’ve made my Default.png “splash screen” image manually from mock ups and screenshots from the simulator — it can be very tedious with mixed results.

There is another way.

Before I show you, you need to know something — it uses a private API function. What does that mean? You need to remove this code before you submit your app to the App Store or it will be rejected. Private APIs are functions not to be used by anyone but Apple. So without further ado:

[[UIApplication sharedApplication] _writeApplicationDefaultPNGSnapshot];

That’s it. You should put this code somewhere in your viewDidLoad function before you load all (but after you load some) of your UI elements. You’ll have to be the judge of the appropriate timing. Once this function is run, it’ll store a PNG screenshot of your application in the following location:

Library/Application Support/iPhone Simulator/VERSION/UDID/Caches/BUNDLEIDENTIFIER/AppSnapshots/

QUICK! Get the screenshot and get outta there — then remove that function.

Load it Faster: Speed Up Your iOS App Loading Time

I’m always thinking about how to make my apps run and load faster. It’s incredibly important, especially to your users. Earlier today I ran across a Twitter conversation (http://twitter.com/flyosity/status/239044820394471424) between a few guys I consider to be top notch: Sam Soffes, Jake Marsh and Mike Rundle. They were discussing best practices for getting your app loading speed down.

There’s a great article by Brent Simmons in which he discusses his methods for making Glassboard 2.2 load faster, it’s available here:
http://inessential.com/2012/08/23/an_iphone_app_startup_performance_techni

Mike also pointed out Sam’s code from Cheddar:
https://github.com/nothingmagical/cheddar-ios/blob/master/Classes/CDIAppDelegate.m#L68

In his didFinishLaunching method, he performs only the most essential tasks and puts everything else in an async queue to run in the background without blocking the main thread. This frees the app up to get the UI and other elements rolling.

On top of this optimization you can do a few things to make your app APPEAR to load faster, namely, a proper Default.png. It’s easy to fall into the temptation to create a cool splash screen but it’s my belief a good Default.png will help “lead” your user into the app and reduces the amount of perceived load time. Apple recommends (http://developer.apple.com/library/ios/#DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/App-RelatedResources/App-RelatedResources.html) you use a screenshot of your initial view with the text and buttons removed. Here are a few examples of good Default.pngs:

WordPress

Colloquy

Cheddar

In reality, Default.png will only show for a second or so but when properly done, in conjunction with a few of the techniques mentioned by the other guys, can help make your app load feel snappier.

It’s a Native Day

Facebook released their native iOS app today, finally putting to rest their wrapped UIWebView HTML5 frankenstein of an app. The performance improvement I’ve noticed thus far is amazing: more responsive, more predictable and noticeably faster — it just feels better.

My experience with iOS development started with PhoneGap and after noticing it just wasn’t going to do what I needed it to do, I started down the road of learning Objective-C and haven’t looked back since. The performance difference and the lack of Nitro in UIWebViews makes a huge difference. You’ll never be cutting edge by cutting corners.

In an article by Eric Allam entitled “Go Native or Go Home” he discusses the benefits of developing natively. He quotes Steve Jobs from his famed open letter to Adobe regarding flash:

We know from painful experience that letting a third party layer of software come between the platform and the developer ultimately results in sub-standard apps and hinders the enhancement and progress of the platform. If developers grow dependent on third party development libraries and tools, they can only take advantage of platform enhancements if and when the third party chooses to adopt the new features. We cannot be at the mercy of a third party deciding if and when they will make our enhancements available to our developers.

This becomes even worse if the third party is supplying a cross platform development tool. The third party may not adopt enhancements from one platform unless they are available on all of their supported platforms. Hence developers only have access to the lowest common denominator set of features. Again, we cannot accept an outcome where developers are blocked from using our innovations and enhancements because they are not available on our competitor’s platforms.

With all the talk of Apple TVs, iPad minis and the simple fact that Apple is continuing to increase their value, there’s never been a better time to learn Objective-C.

Using custom fonts on iOS (iPhone iPad)

This is a quick walk-through on using a font other than those supplied by Apple on an iOS device.

For reference purposes, you can find out what fonts are available to you “out of the box” by checking out this comprehensive list:
http://iosfonts.com/

I’m going to be using Bebas for my example, a great font created by Dharma Type. You can pick it up here: http://www.dafont.com/bebas.font or use a font of your own choice. It’s important to note you should check a font’s license before you use it in an app you intend to distribute in the app store.

If your font’s not installed on your Mac, go ahead and install it. Before we get too deep into coding and while you’re in or around Font Book let’s go ahead and get the PostScript name of your font. You can do this by selecting your font from the list inside of Font Book and pressing Command + I to toggle the font information. The right side of the window will look like this:

The PostScript name is listed on the top, with Bebas, the PostScript name is simple… it’s Bebas but most are more complicated. Take the PTSans family for example: PTSans-Regular to PTSans-CaptionBold. Keep this PostScript name handy as we’ll reference it later.

Moving on let’s get the ttf file into an Xcode project.

I started with a Single View Application template, go ahead and get that going as normal. Inside my Supporting Files folder I’m going to create a group named “Fonts”. I’m going to drag BEBAS___.TTF into that directory and make sure “Copy items into destination group’s folder (if needed)” is checked. Click finish.

Next, open your app’s plist. Right click and add a row, we’re going to add the key “Fonts provided by application” which is an array of the ttf font files. Toggle that down and for Item 0 add BEBAS___.TTF.

Now you need to head over to your project’s build phases tab. Click to the “Copy Bundle Resources” and click the + icon to add a new item and choose BEBAS___.TTF.

Now, when your window looks like this, you’re ready to use the font in the application:

I put some simple code to create a UILabel in my viewDidLoad method like this:

    UILabel *bebasFlavoredLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 0, 320, 44)];
    bebasFlavoredLabel.text = @"Bebas on iPhone";
    [bebasFlavoredLabel setFont: [UIFont fontWithName:@"Bebas" size:15]];

    [self.view addSubview: bebasFlavoredLabel];

On line 3 you see where we use [UIFont fontWithName:@"Bebas" size:15]. The name you use there is the PostScript name you found at the beginning. Go ahead and run:

Viola! Your font is ready to be used as you wish!