Guest Blog Post: The Story Behind Claquette – Animated Screenshots

[Note: This is a guest blog post written by Thomas Zoechling (@weichsel on twitter), a macOS developer based in Austria, about his Mac app Claquette]

Claquette Mac App Icon

Animated GIF is not a good video format.
Actually it even isn’t a proper video format because it lacks random access and audio support. Nonetheless animated GIFs experienced a rennaisance in recent years.
My theory is, that the format’s success doesn’t stem from the features it has, but from the ones it lacks:

  • No random access: Defaults to autoplay – No playback interaction needed
  • No sound: Guarantees silence – Always “Safe for Work”
  • No support for 32bit colors: Moderate file sizes and a characteristic look

Given those constraints, GIFs are a great way to communicate simple concepts or interactions.
Want to showcase an animation or an application feature? Instead of a static screenshot with paragraphs of text, a 3 second GIF works equally well and also draws more attention.

In my daily life as software developer, I often need a quick way to capture graphical bugs. Those clips can be easily shared with colleagues or included with bug reports.
Sometimes it’s also simpler to attach a GIF to customer support requests instead of explaining how a certain feature works.
To cover my own needs, I wrote a small macOS application that allows me to record the screen and export the result as animated GIF. The app uses a custom recording codec and also covers the rest of the GIF creation workflow like crop, trim and file size optimization.

You can download Claquette from the Mac App Store. For detailed product information, please visit our website.

Development

When I started to implement the Animated GIF feature for Claquette, I began with a naïve approach.
Armed with several years of experience in writing Objective-C and some knowledge about video APIs on the Mac, I wrote a small prototype.
That first version just read a video file frame by frame and sent the resulting frames to ImageIO. ImageIO is a system framework that supports reading and writing several file formats.
It also comes with a basic Animated GIF encoder and so I decided to skip any third party libraries and just use the built-in mechanisms of macOS.
I was able to come up with a working prototype in a single afternoon. The program was just a simple command line utility, but it was able to turn an arbitrary video file into an animated GIF.

There was just one problem… Or actually there were several of them: Due to the inner workings of ImageIO, the program used vast amounts of memory. Also, the encoding took very long and the files it created were huge. On top of all that, the resulting GIFs looked horrible.
So while it only took me one Sunday afternoon to create a working prototype, it took me several months to fix the above issues. Especially the large file size and the bad visual appearance of the resulting GIFs required a lot of research.

Getting the most out of a 30 year old file format

The original GIF specification (GIF87a) was written in 1987 – almost 30 years ago. Animation features were added in GIF89a, which is still the most recent version of the format.
So how is it possible that a file format designed for low resolution screens and 256 colors is still in use today?
It turns out that the GIF specification contains some sections that open room for exploitation. Additionally, the visual nature of GIFs allows for optimizations to trick human color perception.

The format is simple and has the following basic structure:

  1. Header
  2. Logical Screen Descriptor
  3. Global Color Table
  4. Graphic Control Extension (Frame #1)
    – Delay
    – Disposal Method
    – Local Color Table
    – Image Descriptor
    – Image Data
  5. Graphic Control Extensions (Frame #2)
  6. Graphic Control Extension (Frame #3)
  7. … (1 GCE for each animation frame)
  8. Trailer

Header and Trailer are basically just magic numbers that mark the start and the end of the file. The Logical Screen Descriptor contains some general image information like width, height and background color. The Global Color Table is a simple list of colors that may contain a maximum of 256 entries.
Main image information is stored in one or more Graphic Control Extension blocks.

Color Table Generation

The color table sections of the format specification are a good starting point to optimize the visual quality of an animated GIF.
Both palettes are restricted by the format’s infamous 256 color limit. When reducing an image that uses 32bit (16.777.216 colors, 256 alpha values) to 8bit (255 colors, 1 alpha bit) it becomes really important which colors you leave out. The process of reducing large palettes to small ones is called Color Quantization. Choosing a good quantization algorithm is crucial when aiming for visually similar images with a reduced palette.
Naïve quantization implementations are based on occurrence, where seldom used colors are left out in the final image. More elaborate algorithms use techniques like dimensional clustering or tree partitioning.

When developing for Apple devices there are several libraries that provide color quantization functionality. macOS and iOS even have basic color quantization algorithms built-in. Apple’s implementation is part of the ImageIO framework’s CGImageDestination API.

The following sample images were created using different quantization techniques. They illustrate the quality impact of the used algorithm on the final image.

CGImageDestination Quantization

The first image shows the output of CGImageDestination. The resulting colors are noticeably off. Apple’s encoder also messes up the transparency color in the GIF palette, which leads to holes in some areas of the image (e.g. the titlebar).

FFmpeg Quantization

The open source library FFmpeg also includes a color quantizer. FFmpeg produces way better results than CGImageDestination. The colors are more vibrant and the transparency color is set correctly.

Claquette Quantization

The color quantization library used by Claquette also outputs a good choice of colors. Additionally the app performs color matching to avoid color shifts and to guarantee correct gamma values.

Frame Difference Calculation

Another important factor during GIF generation is efficient frame difference calculation.
The disposal mode in the Graphic Control Extension allows an encoder to specify how the context is set up before the next frame gets rendered.
GIF89a defines 4 disposal modes:

  • Unspecified: Replaces the existing canvas with the full contents of the current frame.
  • Do not Dispose: Leaves the existing canvas as-is and composites the current (sub)frame over it.
  • Restore to Background: Sets a defined background color and draws the current frame. Areas outside of the subsection in the Image Descriptor shine through.
  • Restore to Previous: Fully restores the canvas to the last frame that did not specify a disposal method.

The Image Descriptor section can be used to define a sub-image which does not provide pixel data for a full frame. Instead it contains coordinates and pixel data for a subsection of the full image.
By using frame differences and sub-images with a proper disposal mode, redundant image data can be avoided. Depending on the nature of the input video, this can greatly reduce the file size of the final GIF.
Modern video codecs like H.264 use techniques like macro blocks and motion compensation. Those methods introduce small errors that propagate from frame to frame. Propagated errors show up as noise when calculating frame diffs and eventually lead to unnecessary large files.
Claquette uses a custom lossless codec, that only stores regions that actually changed. This guarantees exact frame diffs.

The following images show the difference between frame #1 and frame #2 of a screen recording. The only effective change between those frames is a change in the mouse cursor location. An exact diff should therefore only contain an offsetted cursor image.

FFmpeg Diff

The above diff image was created between 2 frames of an H.264 encoded movie. The visible noise is a result of intra-frame encoding errors.

Claquette Diff

The second image was created by Claquette’s image diff algorithm. It only contains the mouse cursor – The only image element that actually changed between frame #1 and #2.

Finishing Touches

After implementing technical details like encoding and optimization, there were still some features missing. Claquette needed an editing UI to handle the whole GIF creation workflow.
As I wanted to keep the app lightweight and simple to use, I decided to add only a small set of editing capabilities: Trim and Crop.
Claquette uses AVFoundation, and therefore I was able to use the AVPlayer class, which comes with a built-in trim tool.
Crop functionality was a bit harder to implement. AVFoundation doesn’t provide any UI component to display crop handles so I had to implement my own.
Besides the standard drag & move interface, my implementation also provides some unique features. It offers alignment guides with haptic feedback and the possibility to enter crop coordinates.

You can see the final implementation of the crop utility in the animated GIF below:

ClaquetteCrop

Launch

To launch the animated GIF feature, I prepared a press kit and wrote mails to review sites that mostly cover Mac software.
Additionally I submitted the app to Product Hunt and informed Apple’s App Store Marketing team.
I can really recommend to launch on Product Hunt: Claquette received over 400 upvotes and finished in the top 3 on launch day. The site also hosts a friendly community, that makes extensive use of the Q&A section below each hunted product.
I was also lucky to get some mentions from high profile Twitter users and good App Store reviews.
Two weeks after launch, Apple suddenly moved Claquette into the “New and Noteworthy” feature section on the Mac App Store front page. Of course this also lead to a noticeable spike in the sales charts.
Overall I was very pleased with the release and the reception of Claquette 1.5.


Thomas Zoechling is an independent software developer living in Vienna, Austria.
Besides working on his own products, he is also doing contract work. Currently he is helping IdeasOnCanvas to develop the excellent mind mapping software MindNode (macOS, iOS).

Post-Mortem: The Mac App Store’s Get Productive Promotion

Get Productive Mac App Store Banner

From January 21st to January 28th, Apple ran a promotion on its App Stores: Get Productive.
I was lucky enough to be asked to participate on the Mac App Store with Yoink, my app that improves and simplifies drag and drop on the Mac.

I thought I’d share my experience with this promotion and some of the stuff that went on behind the scenes.

Getting Invited

It started at the beginning of January, when I received an eMail from a very nice person at Apple, asking if I was interested in putting Yoink on sale for a promotion to happen later in January. I didn’t think too much before responding that I would love to participate – after all, when Apple asks you to participate in a promo, you participate in that promo, there’s no question about it.

It’s not the first time the app partook in a promotion.
In February 2013, Yoink was part of a three-weeks-long productivity promotion on the Mac App Store called “Get Stuff Done” (Yoink was part of the third week – “Utilize”):

Get Stuff Done Week 3 - UtilizeYoink in the Mac App Store’s 2013 Promotion “Get Stuff Done – Utilize” (image credit: macrumors.com)

Thankfully, Yoink did pretty well in that promotion and I think that may have helped in making Apple consider it for this promotion, too.

In case you’re wondering, I don’t have any access or connections to the powers-that-be of the Mac App Store.
However, I do contact them (very rarely, mind you) through iTunes Connect ahead of time if I have a substantial update coming out with information about what’s new and what technologies are used in the update. I do not recommend contacting them about every update you put out – that can only be bad for you, I’m sure.

Pushing my luck, or: Trying to get ScreenFloat included

I realize I should be counting my lucky stars getting one app featured in this promotion.
The thing is, I really believe that another app of mine – ScreenFloat, which takes screenshots and puts them in front of all windows so they’re always visible as a reference to whatever you’re working on – would have been a good fit for the theme of “Get Productive”.
In my mail to Apple, I mentioned ScreenFloat, described it in one sentence and asked if it would be considered.
They did, but the app apparently didn’t make the cut. Since that was what I was expecting anyway, no harm was done and as far as I can tell, they didn’t find it too pushy. Quite the contrary; they seemed very thankful for the suggestion.
I did not receive information about why it was not included, but I have a guess:
I think perhaps the reason they decided not to include ScreenFloat in the sale was its lack of localization – ScreenFloat is localized in English and German, whereas Yoink is available in English, German, Japanese, Simplified Chinese, Korean, Portuguese (Brazil and Europe), French and Italian. Or maybe that it hasn’t received an update in a while (although I am working on version 2.0 these days).

Holding Back an Update

As you’re probably aware, when you release an update on the App Store, its current reviews vanish, the star-rating is averaged over all versions and the new version has 0 (zero) stars.
I was about ready to release an update for Yoink when Apple contacted me, and I knew I had to postpone releasing that update, since if I released it, no stars would be shown next to the app, and I think it does make a difference – it looks much more enticing with stars than without:

Yoink Listing without StarsYoink listing without stars on the Mac App Store

Yoink listing with StarsYoink listing with stars on the Mac App Store

I generally dislike withholding an update to my apps (as I regularly fix bugs and I don’t like knowing that a version with bugs that I have already fixed internally is still out there for users to use), but in this case, I had to make an exception.

It came as a blessing in disguise anyhow since it gave me some extra time to test the soon-to-be-released update and make sure the new Force Touch integration was working as expected.

The Effects of the Promotion

I am more than happy with the results of the promotion. Then again, there’s bound to be a big impact on sales when Apple puts your app (along with other developer’s) in front of (potentially) all Mac App Store users.
Apple calls users to action beautifully (see the first image of this post) – a nice banner with icons of popular apps along with the tag line “limited-time prices”. I know that gets me pushing the Purchase button.

Impact on Sales

As expected, I noticed a significant jump in sales during the promotion.
I’m uncomfortable sharing numbers (something I need to overcome, other developers have shared their numbers and it’s always been helpful), but here’s the curve before, during and after the sale from iTunes Connect:

Yoink Sales through the Get Productive PromotionYoink’s sales graph before, during and after the promotion

James Thomson, developer of PCalc (Mac / iOS), which also participated in the promotion, has also shared his curve on twitter.

Mac App Store Ranking

When the promotion began, Yoink was not in the Top 100 of the Top Paid category in the US at the time.
On January 21st, the app started rising, went to the 43rd place, and on January 22 had its best spot at position 13. It hovered around that spot until the end of the promotion a week later.
It rose to the Top Paid Top 10 in several countries, including China, Japan, Germany and Austria.

Reviews

I did not see a significant increase in the number of reviews – however, the ones I did receive during the campaign were written in China – something I attribute to the fact that, with a recent update of Yoink, I localized it into Simplified Chinese. I haven’t gotten many reviews of Yoink in that country before, so that’s a safe bet.

Support Requests

Surprisingly, requests for support (by mail, twitter or facebook) didn’t come in in the amounts I was expecting and I think that’s a good indication that Yoink is working reasonably well.
Not getting support requests can mean two things: No one purchases it or the software is working more or less without major problems.
Regarding the amount of copies sold, I take not seeing a big bump in support requests as a good thing.

Sponsored Tweets

Yoink's Sponsored Tweet on Twitter

As I mentioned on twitter, I gave Promoted Tweets a try. I put €200,- (around $215) into it and I think it’s safe to say that it’s the most expensive way for me yet of reaching people. On the other hand, the targeting is first-class.

Twitter Promoted TweetPromoted Tweet views (highest: around 14.500 views)

I hand-picked 100 twitter accounts that I thought were relevant to the Mac community (developers, app-accounts, bloggers, journalists), chose interests that I thought were relevant to Yoink and let it fly.
I reached 55.813 people, resulting in 4.142 “engagements”, a conversion rate of 7.4%.
For $215, I can get banner ads on websites that yield 170.000 views and up, but the engagement rate there is much lower.
What is an “engagement”, exactly? It’s a click on the tweet, a click on your profile, a click on the image, a click on the link, a “like” or a retweet. So the engagement rate of 7.4% itself is more or less meaningless.
According to Twitter, I received 35 direct clicks on the link. Thirty-five. That’s an engagement rate of 0.06%. Pretty expensive advertising indeed.

Promoted Tweet EngagementsPromoted Tweet – Engagements

The funniest thing is that some of the people “liking” the tweet ended up blocking me as “spam”. One reply of the two I received was this image:

Spam ReplySpam, anyone?

I ended up on a couple of lists with the specific purpose of blocking me, since I had an ad on twitter. Granted, those were most likely Twitter users who weren’t ever inclined to purchase my software and there are no hurt feelings, I just found it funny.
Seems some users on twitter don’t realise there’s advertisement and figured I spammed them somehow.

The Link for the Sponsored Tweet

In the beginning, I ran a tweet with a link directed to Yoink on the Mac App Store, which later on I discovered was a bad idea.
Most of the users I targeted with this tweet use Twitter on their iOS device and when you open a Mac App Store link on iOS, you receive this:

Mac app in iOS App StoreYoink in the iOS App Store

When you click on “Learn more about this App”, it does take you to the app’s website, but that’s another tap most users are not willing to do.
I changed the link to take them directly to Yoink’s website and only lost about 4.000 views. My bad. (I filed a radar to improve the “Mac Apps page in the iOS App Store” here).

I didn’t like linking directly to my app. I’d rather have linked to the sale, the promotion page where all apps are shown. As far as I can tell, however, that is not possible as of yet (I filed a radar for it, too). It is definitely something that could be improved for future promotions.

Maybe the sponsored tweet may have raised the awareness of Yoink among some users, but I don’t think it was worth it. Perhaps an even more targeted audience would have helped.

TL;DR

Being featured by Apple seriously helps you in getting new customers for your app and I’ll do it again any time they invite me.
Sponsored tweets? Quite expensive for little to no effect (in my case – mind you, it was my first sponsored tweet and I might not have targeted it right. Next time, I might go for a sponsorship of a popular blog instead).

Newsletter

If you enjoyed this blog post, perhaps you’d like to join the Eternal Storms Software Newsletter where I write you once a month at most about what’s going on with my apps and on my blog 🙂 Thank you.

Guest Blog Post: The Story Behind Gestimer

[Note: This is a guest blog post written by Martin Nguyen (@iMaddin on twitter), an OS X- and iOS developer based in Austria, about his Mac app Gestimer]

Gestimer Icon

I don’t like to keep too many thoughts in my head at the same time. Also, my short-term memory isn’t the greatest. If I had to cook dinner and then went back to my Mac to continue whatever I was working on, I’d probably forget about my dinner.

That’s especially true while coding where I have to be completely focused. Other unrelated thoughts are too distracting when writing code. I feel comfortable knowing that an app will take care of such thoughts as its memory is most likely better than mine.

Not too long ago – while I was at university – I noticed that todo apps weren’t entirely fitting all my needs. Sometimes I had these little tasks like reminding me to make dinner (because I’d forget and be too busy or focused with other things) or that I had to leave for a lecture in half an hour. It was too much of a hassle to set alerts for those tasks that have a short lifespan. To me it just feels slow to enter numbers with a keyboard for inputing dates and times, especially without a num pad.

As the type person who sits at my Mac most of the time, I decided to make a Mac app to work around this problem. After a couple of months and failed attempts at such an app, the idea that later became Gestimer popped into my mind: “Wouldn’t it be great if I could just drag down from the menu bar to create a quick reminder?” This seemed so simple and fast. It was the perfect solution.

Development

With this idea in my mind and a few sketches in my notebook, it was time for the execution. This was back in 2012 when I had just begun learning to code. As every beginner knows, coding is frustrating. Everything can break easily and you have no clue why. Objective-C was also not the easiest thing to learn without any prior programming knowledge. Additionally, making Mac apps appeared to be much more difficult than making iOS apps.
I shelved the project. There was nothing that was anywhere close to Gestimer out there so it was impossible finding resources that would help me realize the app.

With iOS 7, Apple introduced UIKit Dynamics. It seemed like a fun way to make interactions so I played around with it. I noticed that UIKit Dynamics allowed me to easily do something close to what I had in mind. It was only available for iOS and not OS X but it still allowed me to produce a version of Gestimer, even if it wasn’t in the intended environment. Here is the iOS version which was available from 2013 to 2014:

Gestimer_iOS

Gestimer for iOS didn’t do too well but that’s okay. I didn’t do any marketing as I simply put it up on the App Store and I was already happy to have an app that I made and used every day. Creating the iOS version taught me a lot and as I learned from more projects over the last couple years, I felt comfortable enough to tackle the Mac version again. I was especially motivated by the announcement and release of Swift.

I made some good progress on Gestimer for the Mac during the summer of 2014. The idea never changed: drag & drop from the menu bar to create a reminder. I worked on the app on and off, whenever I felt like it, whenever I slept off the frustration and head-scratching of the previous day.

As there was no UIKit Dynamics for the Mac, it was a lot more difficult to imitate the iOS version and to get things behaving as intended. By late 2014 I had a rough but useable version. I was never in a rush to release Gestimer. In fact, I stopped working on it for a couple months after that. I was again content with having an app I made and used every day. It also gave me time to simply use the app and think about if it truly did the things well that I wanted it to do.

If you haven’t seen Gestimer yet, have a look at a short clip here.
https://vine.co/v/ehEwHbWKhUj/embed/simple

Marketing

Sometime around mid-April 2015 I started sharing a beta of Gestimer with people who I thought might be interested. Besides gathering feedback, it got me excited about the prospect of launching and hear what even more people will say about it. That’s where I decided to do some proper marketing. I won’t go into detail about this here as it would double the size of this post but I took marketing very seriously.

The basic outline of what I had:
– a short 10s clip of the interaction on the website
– collected email addresses for launch day
– made a YouTube video (currently over 50k views)
– a nice press kit
– localized Gestimer into 9 languages (now even more!)

Launch

There was little press coverage on launch day, but I had Gestimer up on Product Hunt thanks to Matthias who kindly sent me an invite. Someone had also posted the app to Hacker News. Both sites led to a lot of traffic. At the end of the day Gestimer was sitting on the 3rd spot on Product Hunt. To this date, the PH submission for the app has received over 400 upvotes. Twitter also helped a bit, though I believe people overestimate its effectiveness.

More press coverage followed and an increasing number of people spread the word. During launch week Gestimer reached the #1 spot in the Top Paid charts on the Mac App Store in multiple countries including the US, UK, and Germany. While sales numbers on the Mac App Store are small compared to the iOS App Store – even if you reach the top charts – it’s still been good. It’s nothing to complain about.

The reception for Gestimer has been overwhelming and I would have never imagined it becoming this successful. It makes me very proud to have done all the design, code, and marketing work on my own.

If you’d like, you can find out more about Gestimer here.

——
Martin Nguyen (@iMaddin on twitter) sometimes works on iOS and OS X apps and lives in Austria. While he enjoys coding, he is still trying to figure out the next step in his life.