Thursday, December 30, 2010

Goodbye 2010 - Hello 2011

This was an amazing year! Many great things happened and a lot of stuff was released by me. The most important release this year was a personal one. Our third daughter was born in September. Healthy and just plain awesome. She is developing very good and as amazing as her older sisters (photo).
This blog post is just a recap of all the things that happened and I've done in 2010 and some that might happen in 2011.




Community
The whole Silverlight and Windows Phone community is great and it's endless fun to be a part of it. I met a lot of great people online and offline. It's a pleasure to discuss and develop good things in this environment. Thanks a ton!
And don't forget, Silverlight is not dead! Silverlight 5 will be released in 2011 and it will come with a huge bag of new features.
Stay in the 'Light! - like my Silverlight MVP friend Dave Campbell would say.

MVP Award
In April 2010 I was awarded as Silverlight MVP. It is a real honor to be a Silverlight MVP. All the Silverlight MVPs I know are truly outstanding and I can hardly believe I'm considered to be one of them.

Blogging
Yep, I did some blogging this year. Most of it covered Silverlight development and lately also Windows Phone topics. I always try to provide unique content that hasn't been covered anywhere else. I hope you like it and find it useful. Your feedback is always welcome!

Open Source Projects
The one big think this year was the release of the Silverlight Augmented Reality Framework: SLARToolkit. SLARToolkit is a flexible Augmented Reality library for Silverlight with the aim to make real time Augmented Reality applications with Silverlight as easy and fast as possible. It can be used with Silverlight's Webcam API or with any other CaptureSource or a WriteableBitmap. It's open source and hosted at CodePlex.
The development of the library itself took a lot of time, but also the samples (1, 2), the documentation, the support at the forum and via email. It's good to see that some projects use SLARToolkit and the downloads aren't that bad. I'm especially pleased to see that most of the projects are from the academic field. Some projects are listed on the CodePlex site.
I have a lot of things on my idea / todo list I want to add. I hope I'll find a bit time during the next year to implement these.

One part of the SLARToolkit library was extracted and released as separate project. The Matrix3DEx library is a collection of extension and factory methods for Silverlight's Matrix3D struct. The Matrix3DEx library tries to compensate the minimalistic Matrix3D struct with extension and factory methods for common transformation matrices that are easy to use like built in methods. The CodePlex site has all the details and samples.



The WriteableBitmapEx library is another open source project. I actually released it in 2009, but I added a lot of new features during this year and the library got quite well adopted in the community. One reason might be the availability of a Windows Phone version.
The WriteableBitmapEx library is a collection of extension methods for Silverlight's WriteableBitmap. The WriteableBitmap class that was added in Silverlight 3 and which is also available on Windows Phone, allows the direct manipulation of a bitmap and could be used to generate fast procedural images by drawing directly to a bitmap. The WriteableBitmapEx library tries to compensate the minimalistic WriteableBitmap class with extensions methods that are easy to use like built in methods and offer GDI+ like functionality.
There are many different samples available at the CodePlex repository and I also spent a good amount of time with the support at the forum and via email.
The library is still not feature complete for version 1.0 and I will definitely continue my work on it.

Windows Phone Apps
Like many other Silverlight developers I got very exited when Silverlight was announced as the development  platform for Windows Phone 7 apps. I started some experiments right away when the first CTP was available at MIX 2010. I also provided the WriteableBitmapEx Windows Phone version a couple of days later.

Every Windows Phone 7 device is required to have at least a 5 megapixel camera with a flashlight. There are also other features which make Windows Phones amazing devices for taking pictures and dealing with pictures. I've been working heavily during the last months to enhance this photo experience with my kind of skills. My Pictures Lab app was the first picture effects application for Windows Phone with unique, high quality effects. If you like to take photos then this app is a perfect addition to your phone’s toolset. Or like msnbc.com wrote: "The app, a Swiss Army knife of photo tweaks". It's the original and the best selling photo app already since the Windows Phone launch. Pictures Lab comes with more than 20 controllable and easy-to-use advanced effects, a dynamic effect preview, crop, rotate and many more features. I just recently added a Twitter sharing function and the Happy New Year effect / frame (see photo above).
The app got very good reviews from various webites, blogs and offline magazines. The well-known site Engadget lists it under The best apps, accessories, and tips. They write: "... a must-have for WP7 devices ... the program provides a set of amazing effects and tweaks for your photos ...".
I will constantly update the app and add more features and effects in 2011.

I also developed a little fun app called Helium Voice. You can record your voice with the app and change the pitch while sliding over a balloon graphic (inhale or exhale helium).




I have a very long list with future app ideas and it's constantly growing. On some days I have the feeling my head explodes with new ideas.
I hope to find some time next year to push some more apps out. Silverlight is fortunately one of the most productive platforms out there.

Articles
I also wrote some articles for Microsoft's Coding4Fun site and a magazine.

It started with the FaceLight article about a simple facial recognition system using Silverlight 4’s webcam. The code for this article ended up on CodePlex, where you can also find a live sample.






The second article explained how to write pixel shaders for the Microsoft Silverlight and WPF platform with HLSL, as well as how to write an extensible Silverlight application with the help of MEF.
The code is also available at CodePlex.







My last two articles for Coding4Fun showed how to write a simple photo effects application for Windows Phone (1, 2). This is actually where Pictures Lab has its origin.









I just recently wrote an article for Germany's largest .Net developer magazine, dotnetpro. The article covers Windows Phone development and is available in the February 2011 issue and also online.

I also reviewed the media / computer graphics chapters of the two best Silverlight books available. The one is Silverlight 4 Unleashed by Laurent Bugnion and the other is Silverlight 4 in Action by Pete Brown. Both are great books and every Silverlight developer should get a copy.

Talks and the Rest
I gave a talk at the .Net Usergroup Dresden about Silverlight 4's media capabilities and presented SLARToolkit. In May I had the pleasure to be interviewed by Carl and Richard from the .Net Rocks talk show. And I worked on some very interesting projects I can't write something about yet. I also spent a good amount of time answering Silverlight questions I got via email, at the official forum or at Stack Overflow.

It was a really busy year and I hope I can keep this high productivity up.

By the way, I'm also a frequent social network user and met great new people there (Twitter, Facebook). It's a pleasure to exchange thoughts and share knowledge with smart people. Thanks for being awesome!


I wish you and your families a happy and successful new year. 2011 will be good!

Wednesday, December 29, 2010

Sending Windows Phone Screenshots in an Email

My Silverlight MVP friend Laurent Bugnion blogged about how to take a screenshot from within a Silverlight Windows Phone application. As he wrote this could be helpful for customer feedback and other purposes. To accomplish this, the Silverlight UIElement is rendered to a WriteableBitmap, which can then be saved to the device's Media Library (Pictures Hub). Afterwards it could be send in an email from the Pictures Hub or the email client.
Wouldn't it be even nicer if the user could send an email with the screenshot directly from the app? I show you how.

The Email Task
The only way to send an email from a Windows Phone app is through the EmailComposeTask. This task provides properties for the Subject, Body, CC, Addressee (To) and launches the email client. In the last blog post I showed how I use it to send customer feedback with system information from my apps.
Unfortunately the EmailComposeTask doesn't provide a way to pass an attachment and therefore it's not possible to attach the screenshot to the email. Fortunately there's a way to send binary data as text inside an email. This is where Base64 encoding comes into play.

Embedding the Screenshot 
Base64 encoding transforms binary data into ASCII text and thereby makes it possible to send binary data as plain old text. This way we can convert the JPEG screenshot to Base64 text and set it as the Body of the EmailComposeTask. The Body text length is limited and I experimented a bit with different sizes to find the limitation. It seems like the Body text is limited to less than 32k Unicode characters. A JPEG encoded screenshot of a whole Windows Phone page is too large for this (480 x 800 pixels). That's why the screenshot is rendered downscaled if the element is too large and a lower compression quality is used for the JPEG encoding.
private static void SendEmailScreenshot(FrameworkElement element)
{
   // Render the element at the maximum possible size
   ScaleTransform transform = null;
   if (element.ActualWidth * element.ActualHeight > 240 * 400)
   {
      // Calculate a uniform scale with the minimum possible size
      var scaleX = 240.0 / element.ActualWidth;
      var scaleY = 400.0 / element.ActualHeight;
      var scale = scaleX < scaleY ? scaleX : scaleY;
      transform = new ScaleTransform { ScaleX = scale, ScaleY = scale };
   }
   var wb = new WriteableBitmap(element, transform);

   using (var memoryStream = new MemoryStream())
   {
      // Encode the screenshot as JPEG with a quality of 60%
      wb.SaveJpeg(memoryStream, wb.PixelWidth, wb.PixelHeight, 0, 60);
      memoryStream.Seek(0, SeekOrigin.Begin);

      // Convert binary data to Base64 string
      var bytes = memoryStream.ToArray();
      var base64String = Convert.ToBase64String(bytes);

      // Invoke email task
      var emailComposeTask = new EmailComposeTask
                              {
                                 Subject = "Screenshot from my app",
                                 Body = base64String,
                                 To = "foo@bar.com",
                              };
      emailComposeTask.Show();
   }
}
The element is downscaled uniformly if it's larger than a certain size. This is done with a ScaleTransform directly when the Silverlight (vector) element is rendered to a WriteableBitmap. Afterwards the bitmap is encoded as JPEG at a quality of 60%. This low compression quality reduces the size of the JPEG image significantly, but the image is still usable. The binary data is then transformed to Base64 text with the Convert.ToBase64String method. Finally the EmailComposeTask is created, the properties are set and the email client is opened.

Decoding the Screenshot
The email will contain the Base64 encoded image. Base64 encoded data typically looks like this:
/9j/4AAQSkZJRgABAQEBBgEGAAD/2wBDAA0JCgsKCA0LCgsODg0PEyAVExISEyccHhcgLikxMC4pLSwzOko
+MzZGNywtQFdBRkxOUlNSMj5aYVpQYEpRUk//2wBDAQ4ODhMREyYVFSZPNS01T09PT09PT09PT09PT09PT09PT09PT
09PT09PT09PT09PT09PT09PT09PT09PT09PT0//wAARCAFsAPADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAA
AAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM
2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJW
Wl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAw

...

The opposite operation of the ToBase64String method is the Convert.FromBase64String method. So it's easy to write a little tool that extracts the email content, converts it back to JPEG data and saves it as a file for example. Probably it's sufficient to use an online Base64 encoder like this one where the Base64 string can be pasted and the tool will create a binary file which can be downloaded.

The result might look like the below screenshot from the Pictures Lab app. As you can see, the half downscaled version with the 60% quality is usable and even the small text can be read without problems.


Future
There's also room for improvement left. More modern image compression algorithms like they are used in the Hipix or WebP formats can produce better results at lower size. Another way to reduce the size could be a post process step where every odd pixel or line is removed. This technique was described in the Kill Pixel Shader blog post.
Needless to say that the demonstrated, well-known Base64 encoding can be used to send any small binary data inside an email from a Windows Phone app. So it's also possible to send short audio clips, binary serialized data or other data.

Conclusion
For more complex tracking and feedback mechanisms an image upload webservice might be the better way. However there are many scenarios with simple tasks where a webservice isn't feasible and the shown technique can be helpful.

Monday, December 20, 2010

Listen to your Phone - Getting User Feedback with System Information

Two weeks ago I've blogged about a trick my Windows Phone Pictures Lab app uses to detect if the Zune software is running. Today I have a handful of classes that help to gather system information and provide an easy interface for the email task. No magic at all, but I though it might be helpful for others too.
I use these helpers in Pictures Lab for the user feedback functionality. I got a lot of valuable feedback and great suggestions via this feature.
The user can invoke this functionality on the about page of the app and it's also fired when an unhandled exception occurred and the user wants to send error details.

System Information
It's always useful to include some system, version and device information in such a feedback report. That's why I wrote a SytemInformation class which queries some paramteres and creates a nice, human readable string.
public class SystemInformation
{
   public static string Dump()
   {
      var builder = new StringBuilder();
      builder.AppendLine("***** System Infos *****");
      builder.AppendLine();
      builder.AppendFormat("Time: {0}", DateTime.Now.ToUniversalTime().ToString("r"));
      builder.AppendLine();
      builder.AppendFormat("Culture: {0}", CultureInfo.CurrentCulture);
      builder.AppendLine(); 
      builder.AppendFormat("App Version: {0}", WmAppManifestHelper.GetVersion());
      builder.AppendLine();  
      builder.AppendFormat("Manufacturer: {0}", DevicePropertiesHelper.GetDeviceManufacturer());
      builder.AppendLine(); 
      builder.AppendFormat("Model: {0}", DevicePropertiesHelper.GetDeviceModel());
      builder.AppendLine(); 
      builder.AppendFormat("DeviceHardwareVersion: {0}", DevicePropertiesHelper.GeDeviceHardwareVersion());
      builder.AppendLine(); 
      builder.AppendFormat("DeviceFirmwareVersion: {0}", DevicePropertiesHelper.GeDeviceFirmwareVersion());
      builder.AppendLine(); 
      builder.AppendFormat("OS  Version: {0}", Environment.OSVersion);
      builder.AppendLine(); 
      builder.AppendFormat("CLR Version: {0}", Environment.Version);
      builder.AppendLine(); 
      builder.AppendFormat("Device Type: {0}", Microsoft.Devices.Environment.DeviceType);
      builder.AppendLine(); 
      builder.AppendFormat("Network Type: {0}", NetworkInterface.NetworkInterfaceType);
      builder.AppendLine(); 
      builder.AppendFormat("DeviceTotalMemory: {0:f3} MB", DevicePropertiesHelper.GetTotalMemoryMb());
      builder.AppendLine(); 
      builder.AppendFormat("ApplicationPeakMemoryUsage: {0:f3} MB", DevicePropertiesHelper.GetPeakMemoryUsageMb());
      builder.AppendLine(); 
      builder.AppendFormat("ApplicationCurrentMemoryUsage: {0:f3} MB", DevicePropertiesHelper.GetCurrentMemoryUsageMb());
      builder.AppendLine(); 
      using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication())
      {
         builder.AppendFormat("Iso Storage AvailableFreeSpace: {0:f3} MB", appStorage.AvailableFreeSpace / 1024f / 1024f);
         builder.AppendLine();
      }
      return builder.ToString();
   }
}
As you can see a few interesting properties from the OS, the device and its configuration and memory status are queried. This is done with built-in and custom helper classes.
The WmAppManifestHelper class parses the WmAppManifest.xml file and provides the app version and other properties from this file. The DevicePropertiesHelper wraps the DeviceExtendedProperties class and the available property keys. I added all the keys I need, but not more (YAGNI). However, if you add more property keys to the class, please make sure to post a comment.


Email Service
The EmailService class wraps the EmailComposeTask and adds the system infos to the body of the email.
public class EmailService
{
   private readonly EmailComposeTask emailComposeTask;

   public string Addressee { get; set; }

   public EmailService()
   {      
      Addressee = "foo@bar.com";
      emailComposeTask = new EmailComposeTask();
   }

   public void ShowTask(string subject, string body)
   {
      // Add system infos add the end of the email
      body += Environment.NewLine;
      body += Environment.NewLine;
      body += Environment.NewLine;
      body += Environment.NewLine;
      body += SystemInformation.Dump();

      // Fill email
      emailComposeTask.To = Addressee;
      emailComposeTask.Subject = subject;
      emailComposeTask.Body = body;

      // Invoke Mail Task
      emailComposeTask.Show();
   }
}
The ShowTask method sets the properties of the EmailCompoaseTask and opens it. The addressee can be defined with the corresponding property.


Please replace the foo@bar.com default value for Addressee with your email address. Think about the poor Foo at bar.com.










Handling the Unhandled
This email functionality is used to enable explicit user feedback when the user taps the 'submit feedback' button. It is also utilized in the UnhandledException event handler of the Application class. The default body of the event handler in the App.xaml.cs file is generated by Visual Studio when a new Windows Phone Application project is created. Just add the email service and set the e.Handled property to true.
private static void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
   var result = MessageBox.Show("An error occured. Do you want to send the error details to the developer?", "Meh", MessageBoxButton.OKCancel);
   if (result == MessageBoxResult.OK)
   {
      new EmailService().ShowTask("App error", e.ExceptionObject.ToString());
   } 
   e.Handled = true;
}

The body of such an error email would then look like this
System.ArgumentException: The parameter is incorrect. 
   at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
   at MS.Internal.XcpImports.SetValue(INativeCoreTypeWrapper obj, DependencyProperty property, DependencyObject doh)
   at MS.Internal.XcpImports.SetValue(INativeCoreTypeWrapper doh, DependencyProperty property, Object obj)
...


***** System Infos *****

Time: 12/11/2010 5:50:02 PM
Culture: en-US
App Version: 1.9.0.0
Manufacturer: SAMSUNG
Modell: SGH-i917
DeviceHardwareVersion: 3.1.0.7
DeviceFirmwareVersion: 2103.10.10.1
OS  Version: Microsoft Windows CE 7.0.7004
CLR Version: 3.7.10218.0
Device Type: Device
Network Type: MobileBroadbandGsm
DeviceTotalMemory: 475.469 MB
ApplicationPeakMemoryUsage: 63.055 MB
ApplicationCurrentMemoryUsage: 41.223 MB
Iso Storage AvailableFreeSpace: 601.641 MB

Conclusion
User feedback is always valuable and every serious Windows Phone developer should at least add a simple functionality like the one presented here.

Source Code
You can download all mentioned classes here. Please comment if you know more useful system infos that should be included.

Thursday, December 9, 2010

Issue with the WP7 PictureDecoder and Workaround

This is fixed in the WP 7.1 SDK /  WP 7.5 / Mango!
I noticed a strange behavior of the Windows Phone PictureDecoder DecodeJpeg method while I was working on my Pictures Lab app.
This short post describes the issue I encountered and also provides a workaround.
The built-in DecodeJpeg method decodes a JPEG image stream into a WriteableBitmap. The method has two overloads, where the first only takes the JPEG stream and the second also uses parameters for the maximum width and height of the output. I encountered a strange behavior of the latter method.

Issue
The DecodeJpeg method with 3 parameters swaps the width and the height parameters when a landscape photo should be resized. For example, an image with the original size of 3264 x 2448 should be decoded to a WriteableBitmap and resized to 1024 x 768. But the resulting output will have a size of 768 x 576 cause the method swapped the input parameters while preserving the correct aspect ratio.
Please note that this only happens with landscape pictures, which means the width of the image is greater than the height.

Will it get fixed?
Yes! I contacted Microsoft and they confirmed this issue and said that it will get fixed in a future version of the Windows Phone Silverlight runtime.

Workaround
Isolating the cause of this strange behavior took a bit of time, fortunately the easier was the obvious workaround.

int w = desiredOutputWidth;
int h = desiredOutputHeight;

// Workaround for issue in DecodeJpeg method:
// Swap width and height for landscape pictures.
if (originalWidth > originalHeight)
{
   w ^= h;
   h ^= w;
   w ^= h;
}
var writeableBitmap = PictureDecoder.DecodeJpeg(jpegStream, w, h);
The code tests if the original width is greater than the height and then swaps the output width and height using the good old XOR swap trick.
Alternatively you can avoid the DecodeJpeg overload with the resizing functionality, decode the full sized image and use the WriteableBitmapEx Resize method afterwards. It produces similar results when bilinear interpolation is used, but it's an extra step that costs resources.

The above photo was taken with a HTC Mozart and edited with Pictures Lab (cropped, rotated and 1989 vintage effect).

Windows Phone Unplugged - How to Detect the Zune Software

I've been blogging about Windows Phone development since the first CTP version and also blogged about the photo and camera API.
This post will cover a little trick my Pictures Lab app uses to detect if the Zune software is running when the device is connected to the PC. This is important because the device's media Hubs can't be accessed when the device is connected and the Zune software is running. The same is true for the media APIs (PhotoChooser, MediaLibrary, ...).
The Pictures Hub and the Zune Hub show a little animation when you try to open these while Zune is running. Unfortunately there's no built-in method to detect this in code.

An app mostly performs the classic IPO Model operations: load, process, save. The load and save steps can fail when Zune is connected. The following two code snippets show how to detect if the Zune software is running and ask the user to close it. I use the PhotoChooser and MediaLibrary here to demonstrate this exemplarily for picture handling, but the same is also valid for other media like audio.

Save fail
If the device is connected to the PC and the Zune software is running, an InvaildOperationException is thrown.
By the way, this blog post covered how to save a WriteableBitmap as JPEG to the device's media library.

private static void Save(WriteableBitmap bitmap)
{
   try
   {
      SaveToMediaLibrary(bitmap, "mySuperCoolPic.jpg");
   }
   catch (InvalidOperationException)
   {
      MessageBox.Show("The Zune software is running and the picture can't be saved. Please close Zune or disconnect the phone.");
   }
}
This is quite straightforward.


Load fail
Unfortunately it's not that easy to detect if the Zune software is running when a picture is opened through the PhotoChooserTask API. (How to use this Task was also covered here.)

Some users contacted me when they tried to open a photo with Pictures Lab and nothing happened. The problem is that the picture viewer just won't open when the PhotoChooserTask.Show method is called and Zune is running on the PC. There's no built-in feedback here. I implemented the following code in the Completed event handler of the PhotoChooserTask to get a better user experience.

private void PhotoProviderTaskCompleted(object sender, PhotoResult e)
{
   try
   {
      if (e != null)
      {
         if (e.TaskResult == TaskResult.OK)
         {
            // Do something with the JPEG stream in e.ChosenPhoto
         }
         else if (e.Error is InvalidOperationException)
         {
            throw e.Error;
         }
         else if (e.TaskResult == TaskResult.Cancel)
         {
            // Try to get an image from the Pictures Hub. 
            // If this fails, the device is connected and Zune is running.
            var pictures = new MediaLibrary().Pictures;
            if(pictures.Count > 0)
            {
               pictures[0].GetThumbnail();
            }
         }
      }
   }
   catch (InvalidOperationException)
   {
      MessageBox.Show("The Zune software is running and the picture can't be saved. Please close Zune or disconnect the phone.");
   }
}
One might wonder why the MediaLibrary is queried when the PhotoResult EventArgs has the Error property. Unfortunately it's not used when Zune is running, only the TaskResult is set to Cancel in this case. This TaskResult value is also used when the user presses the back button while choosing a photo and it's not clear why the TaskResult was set to Cancel.

Fin
That's it.
I hope it helps.
Let me know if you found a better way.

The above photo was taken with a HTC Mozart and edited with Pictures Lab (cropped and Lomo effect).

Tuesday, November 2, 2010

Tracking Sales Statistics with the Silverlight Analytics Framework for Windows Phone

The official statistics are now available at the App Hub portal. However, this approach is capable of more than sales tracking.

Are you a Windows Phone developer? Are you also curious how well your app performs in the Windows Phone Marketplace? I am!
Some might say it doesn't matter yet, since there aren't many devices out there, but nevertheless I'd like to know my statistics. Also O2 Germany recently reported they have sold out the first batch of HTC HD7 devices with sales in the 5-figure range. Unfortunately we won't see official statistics from the Marketplace any time soon. An App Hub forum member contacted the Microsoft App Hub support and they told him that sales statistics won't be available before January 2011. Bummer!
Fortunately we are app developers and we can implement our own statistic tracking. On the other hand this means we have to setup and pay some service and implement tracking code. Here is where the Silverlight Analytics Framework and Google Analytics come to the rescue.
This blog post provides a step-by-step guide on how to track your app (sales) statistics with the Silverlight Analystics Framework and Google Analystics. Did I mention it's free and not only free for a limited period?
Let's go...

Setup Google Analytics
If you don't have a Google Analytics account, just sign up here. It's free.
  1. Create an empty HTML page with the minimum tags and upload it to some public webspace. If you don't have webspace available, just create a free Dropbox account and put the page in the public folder.

  2. Go to Google Analytics and use the "Add Website Profile" functionality. Choose "Add a Profile for a new domain". Enter the URL of the dummy website.

  3. The next page setup page will show the necessary Java Script tracking code. Copy the code, paste it into the dummy website and upload the website.

  4. Your website profile is now waiting for activation. Go back to the overview and click the Edit link of your website profile. See the little yellow exclamation mark with the text "Tracking Not Installed" at the upper right corner. Click on "Check Status". The status should change soon and the profile will become active. If not, give Google a couple of minutes and retry it then.


Setup the Silverlight Analytics Framework
Now it's time to submit the tracking events from your app to Google Analytics. This task is pretty easy with the help of the Silverlight Analytics Framework.
The Silverlight Analytics Framework is an extensible web analytics framework mainly developed by the Microsoft evangelist Michael S. Scherotter. It's really nice, designed in a flexible way with the use of modern technologies and open source. Google Analytics is just one of the many supported analytics services.
  1. Download the latest version from the Codeplex site and install it or download the latest source code from the repository and build it yourself. I've chosen the latter since Michael recently implemented a nice feature: The Silverlight Analytics Framework for Windows Phone tracks each page view by default. In the changeset 63020 Michael added an IsPageTracking property which allows to disable the page tracking. This feature is part of the latest release 1.4.8.

  2. Add the following assembly references to your project.
    From the Silverlight for Windows Phone Framework: System.Device, System.Windows.Interactivity
    From the Silverlight Analytics Framework: Microsoft.WebAnalytics, Microsoft.WebAnalytics.Behaviors, Google.WebAnalytics, System.ComponentModel.Composition, System.ComponentModel.Composition.Initialization

  3. Create a new class in your project:
    public class AnalyticsService : IApplicationService
    {
       public void StartService(ApplicationServiceContext context)
       {
          // Wire up MEF
          CompositionHost.Initialize(
             new AssemblyCatalog(
                Application.Current.GetType().Assembly),
                new AssemblyCatalog(typeof(Microsoft.WebAnalytics.AnalyticsEvent).Assembly),
                new AssemblyCatalog(typeof(Microsoft.WebAnalytics.Behaviors.TrackAction).Assembly));
       }
    
       public void StopService() { }
    }
    

  4. Go to the App.xaml file of your project and add the namespace definitions to the first tag:
    <Application
        x:Class="MyApp.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    
        
        xmlns:local="clr-namespace:MyApp"
        xmlns:ga="clr-namespace:Google.WebAnalytics;assembly=Google.WebAnalytics"
        xmlns:mpc="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:mwa="clr-namespace:Microsoft.WebAnalytics;assembly=Microsoft.WebAnalytics"
        >
    
  5. Then add the service references inside the Application.ApplicationLifetimeObjects declaration in your App.xaml file:
    <Application.ApplicationLifetimeObjects>    
        <local:AnalyticsService />
        <mwa:WebAnalyticsService IsPageTrackingEnabled="False">
            <mwa:WebAnalyticsService.Services>
                <ga:GoogleAnalytics WebPropertyId="UA-XXXXXXX-X" />
            </mwa:WebAnalyticsService.Services>
        </mwa:WebAnalyticsService>
    </Application.ApplicationLifetimeObjects>
    
    Most important you need to replace the WebPropertyId in the GoogleAnalytics element with the Id of your newly created Google Analytics website profile.
    I'm not interested in the page tracking, therefore I've set the IsPageTrackingEnabled property to False. You should also keep in mind that page tracking has an impact on the performance of the app. I recommend to disable it.
     
  6. Since your app is now using a network connection, you need to add the ID_CAP_NETWORKING capability to your WMAppManifest.xml file
That was all to get the Silverlight Analytics Framework connected to your Google Analytics profile. It now tracks the Deactivated, Activated and Started events.
You can find the results here:

Please keep in mind that it usually takes 12 - 24 hours until the tracked data shows up in Google Analytics.


Add sales tracking
There's only one puzzle piece left now, the actual sales tracking. I use two Windows Phone APIs for this. First the LicenseInformation.IsTrial method which tells us if the app runs in trial mode or if it was paid. The second API is the DeviceExtendedProperties class with the DeviceUniqueId key which provides a unique 20 byte long hash for the phone. Such an id is needed to count unique installations.
  1. Add a new class to your project for the explicit tracking from code:
    public class AnalyticsHelper
    {
       // Injected by MEF   
       [Import("Log")]
       public Action<AnalyticsEvent> Log { get; set; }
    
       public AnalyticsHelper()
       {
          // Inject
          CompositionInitializer.SatisfyImports(this);
       }
    
       public void Track(string category, string name)
       {
          // Track analytics event
          Log(new AnalyticsEvent { Category = category, Name = name, });
       }
    }
    

  2. Call the Track method when your app launches and provide the necessary information.
    Add this code to the Application_Launching event handler in the App.xaml.cs file.
    private void Application_Launching(object sender, LaunchingEventArgs e)
    {
       var analyticsHelper = new AnalyticsHelper();
    
       // Get device id
       var value = (byte[])DeviceExtendedProperties.GetValue("DeviceUniqueId");
       var id = Convert.ToBase64String(value);
       
       // Track launch
       analyticsHelper.Track("Launch All", id);
    
       // Track if paid
       if (!new LicenseInformation().IsTrial())
       {
          analyticsHelper.Track("Launch Paid", id);
       }
    }
    
    Gergely Orosz (@Gergely Orosz) gave me the idea to track the statistics only if the phone is connected to Wi-Fi. This is pretty easy to implement, just add an if condition around the tracking: NetworkInterface.NetworkInterfaceType == NetworkInterfaceType.Wireless80211

  3. The app is now using the unique id of the phone, so you have to add the ID_CAP_IDENTITY_DEVICE capability to your WMAppManifest.xml file

As you can see all app launches are tracked in the category "Launch All" and all paid launches in the "Launch Paid" category. This makes it easy to see all installations and all sales directly. Needless to mention that Launch Trial = Launch All - Launch Paid.
You can check if all works with the Fiddler or the TCPView tool while using the Windows Phone emulator. By the way, the tracking is pretty fast. I measured 20 to 40 ms for each Track call when the phone was connected to Wi-Fi.

The tracked events are best viewed when grouped by categories. The screenshot below shows a test with multiple launches of a phone and the emulator. The total number of events is listed at the bottom right of the table. Note that Unique Events aren't significant here since they only represent unique events for one session.

The id (event name) we supply through the AnalyticsEvent is mapped to the Google Analytics Event Action. You can find all event mappings and more info in the relevant Silverlight Analytics Framework documentation.

Conclusion
The update I submitted to the Marketplace works nicely and I hope to see some meaningful statistics in the next weeks. I think the described method is a good way to track your sales and other statistics until the App Hub team provides the official usage / sales statistics. Actually the provided tracking functionality is even useful when the App Hub team provides official statistics. And it's all free without a limited timeframe.

Monday, November 1, 2010

Silverlight is not dead and not undead either

No, it's alive and kicking.
You might have heard about the rumors that came up after the PDC conference and Bob Muglia's interview with Mary Jo Foley. Many people flooded Twitter and other sites with speculations that Silverlight is dead for the web. Microsoft's President of the Server and Tools Division Bob Muglia just clarified the situation.

"Make no mistake; we’ll continue to invest in Silverlight and enable developers to build great apps and experiences with it in the future."

You should also read the blog post from the Silverlight program manager Tim Heuer. Without a doubt he puts all his effort into the success of Silverlight. And not to forget the Microsoft Silverlight evangelist John Papa who also proves his commitment to Silverlight here.

Now let's get back to work...

The picture is an old poster from the movie Santo en el Museo de Cera with the famous Mexican lucha libre wrestler El Santo.

Monday, October 18, 2010

Pictures Lab for Windows Phone

"Windows Phones are going to be absolutely amazing devices for taking pictures and dealing with pictures." - Joe Belfiore at the official Windows Phone 7 launch event in NYC. I totally agree, they are. Just think about that each device needs to have at least a 5 megapixel camera and the little camera button with the "pocket to picture" functionality. I've been working heavily to enhance this photo experience with my kind of skills. This blog post contains information about the Windows Phone app I created and will also provide the references to how it works internally.


Download here

Pictures Lab is the ultimate picture effects app for all Windows Phone device types.
MSNBC.com: "a Swiss Army knife of photo tweaks".
Engadget.com: "a must-have for WP7 devices ... the program provides a set of amazing effects and tweaks for your photos"
Gizmodo.com : "Pictures Lab offers a ton of effects for your money."

If you like to make beautiful photos, then this app is a perfect addition to your phone’s toolset. Pictures Lab provides you with thousands of different modifications for your photos and has a camera functionality with superior features like face detection auto focus, steady mode and much more. It's also integrated as a Lens.
Pictures Lab is the original with high quality filters, features and great user experience. It's fast and responsive and you quickly get your job done with just a few moves. Often been copied, but never reached.
Microsoft uses Pictures Lab in its presentations as a "delightful app" which "Looks and feels like an integral part of Windows Phone". "Uncluttered, polished experience".

The app comes with controllable, easy-to-use, but advanced effects like different vintage and hipster-like filters, Tilt Shift (miniature faking), HDR, Lomo, Soften, Auto Adjust, Sharpen, Comic, Bulge, B&W, Sepia and many more. Dynamic previews of the effects are shown in a list, making it possible to easily pick the right one. The high quality borders are also presented in a nice preview list and can be combined with any filter and any aspect ratio. Multiple effects can also be combined.
It is also possible to crop, rotate and flip images. An enhanced picture and the EXIF data can be saved to the phone’s pictures hub or shared directly on Facebook, Twitter and other social networks. Later editing is also supported. The app performs the image processing on the original picture in its original resolution, thus making it also possible to print the image or use it as desktop wallpaper.
Full Pictures Hub Apps integration and support for landscape and portrait orientation. Trial version with complete functionality only save is disabled.

    If YouTube works better for you.

Reviews
  • The well-known site Engadget lists it under The best apps, accessories, and tips. They write: "... a must-have for WP7 devices ... the program provides a set of amazing effects and tweaks for your photos ..."
  • Gizmodo included Pictures Lab in Windows Phone 7 Essential Apps, Reviewed. They also recorded a video. They write: "Your phone isn't complete until you can take photos that look like they came out of a $5 camera from 1974. Pictures Lab fortunately offers a ton of other effects for your money. $2."
  • Gizmodo Australia also featured it in the article The Best Windows Phone 7 Apps.
  • msnbc.com wrote: "The app, a Swiss Army knife of photo tweaks, will be one of my first downloads."
  • techradar.com wrote that Pictures Lab is the #1 app worth paying for: "Tilt-shift effects, crop and rotate... Pictures Lab combines the fun effects of an iPhone photo app like Hipstamatic with the useful fixes you're mostly likely to need (sharpen and - in the imminent update - crop) in a beautifully designed app that crosses the power of Silverlight with the tools of the Windows Phone 7 interface. Pick a photo, see all the possible effects as thumbnails or swipe up and down to try them one at a time."
  • msnbc.com listed it in the article: "The first Windows Phone 7 apps you should grab"
  • MSN UK listed it under the "20 top mobile phone app". And they put my fat nose on the front page. Fortunately two of my girls brought the beauty back to the page.
  • America's popular WIRED magazine with a circulation of 800,000 featured Pictures Lab in there special edition WIRED App Guide.
  • UK's popular gadget magazine T3 with a circulation of more than 60,000 featured Pictures Lab in the 02/2011 issue on the page: "Killer Apps"
  • Pictures Lab was featured in Channel 9's Hot Apps series.
  • Nokia writes "it’s the closest thing to having Photoshop on your mobile phone."
  • Nokia included Pictures Lab in Top of the Apps: 10 Hotties.
  • Softpedia featured the Windows Phone 8 update.
  • All About Windows Phone reviewed the app: "Pictures Lab is one of many photo toolboxes for your smartphone, but it's the one that I enjoy using the most." and "Very, very much recommended."
  • All About Windows Phone also reviewed the Windows Phone 8 update: "It goes significantly beyond the one shot filters typically offered in apps of this type (Nokia Creative Suite, HTC Photo Enhancer) to the point at which it's about a lot more than just fun filters."
  • Another very popular UK magazine Stuff wrote a 5 stars review in the March edition. They write that Pictures Lab is better than a well-known iPhone app.  
  • Germany's popular media and design magazine PAGE with a circulation of 20,000 featured Pictures Lab in the 01/2011 issue
  • Microsoft features Pictures Lab in their presentation slides for Windows Phone under the category delight: "Looks and feels like an integral part of Windows Phone 7". "Uncluttered, polished experience".
  • Geek.com listed it as one of the Five must have apps for Windows Phone: "Pictures Lab is $2.99, but well worth it in my opinion for all of the new features added to the camera on your phone."
  • The famous blogger Scott Hanselman says in his Essential Apps blog post: "Pictures Lab is a nice effects and editing application (if not THE BEST editing app) for Windows Phone. All the functionality is there and cleanly integrated with the Photos Hub. Crop, Rotate, Effects, etc. It's a must-have if you are doing any photography on your phone."
  • Business Insider writes "Pictures Lab is like Instagram for Windows Phone 7. Take pictures with Pictures Lab, apply filters, and share them with friends."
  • The famous design site Smashing Magazine included Pictures Lab as an example in the article Introduction To Designing For Windows Phone 7 And Metro
  • Bright Hub lists Pictures Lab as the first app in Top 5 Samsung Focus Apps: "It is considered one of the most popular photo editing programs on the Windows Phone platform, and for good reason. It has an array of sophisticated and beautiful effects ..."
  • APC (Australian Personal Computer) writes: "WP7’s best picture editing and effects app.Pictures Lab has received a lot of attention as the “go-to” image editing suite for new WP7 users – and for good reason, too."
  • Mobility Digest wrote: "This app makes me happy. Tons of features, seems simple to use and it’s cheap – that’s a win! It even has a trial mode that includes all effects."
  • Mobility Digest also posted a walk through: "I didn’t realize it, but when you go to the list of available effects you get to see a preview of the effect which is really great and I have to say, I’m really impressed for how much this app can do."
  • Mobility Digest listed it in: "The First 25 Windows Phone Apps To Download"
  • Pocket-Lint wrote in the article Best Windows Phone 7 photography apps: "... the smart way to go is with Pictures Lab..."
  • maximumpc.com wrote: "Speaking of pictures, for two bucks you can have a great little mobile suite of photo effects, fixes, and basic editing tools. The Windows Phone 7 UI language really shines through in this one."
  • Mobile Choices listed it as one of the two Windows Phone apps in The 12 best Christmas apps: "...turning lifeless images into photographic masterpieces..."
  • The blog Noisecast recorded a nice video review: "The program @PicturesLab is the best photo editor for Windows Phone 7, hands down."
  • 1800pocketpc.com wrote: "If you love to add effects to your picture then this is one app video you wouldn’t want to miss."
  • 1800pocketpc.com also wrote a review including a video
  • wpcentral.com wrote: "... interesting photo effect application."
  • wpcentral.com also got the WP8 update and : "... Things fly along nicely and the effects don’t take too long to apply in full ..."
  • mobiledownloadblog.com wrote: "There is no doubt that any phone device is incomplete without good picture depiction. A fantastic photograph app known as Picture Lab is now available for Windows Phone 7."
  • Techland.com has it on the list: "50 Windows Phone 7 Apps to Get You Started"
  • mobiledownloadblog.com has it on the list: "Samsung Focus: 30 Best WP7 Applications"
  • The German site phoneseven.de wrote: "Die App sieht wirklich klasse aus und lässt sich allem Anschein nach wirklich gut bedienen. Wer also befürchtet hat, dass Windows® Phone 7 zu wenig Möglichkeiten für gute Apps bietet, der wird mit Pictures Lab sicherlich eines besseren belehrt. Die App wird sicherlich zu meinen ersten Käufen aus dem Marketplace gehören."
  • The Portuguese site pcdebolso.com also wrote an article: "Pictures Lab a caminho do Windows phone 7"
  • Dave Campbell wrote a nice review: "All-in-all, I give Pictures Lab 5 stars"
  • John Papa wrote: "Overall, very nice app, good UI, snappy (which was a surprise to me since it does a lot)."
Feature list
  • Full support for Windows Phone 7 and 8 including all screen resolutions.
  • 30 advanced effects: Ten different vintage and hipster-like effects, Tilt Shift (miniature faking), HDR, Lomo, Soften, Auto Adjust, Sharpen, Comic, Bulge, B& W, Sepia, Manual, Edge Detection, Night Vision, Rainbow, Mirror, X-Ray, Heat Image, Colorization, Negative and Bitmap.
  • Editable effect parameters with ready-to-use default values.
  • Combination of multiple effects.
  • 11 high quality borders and more seasonal borders.
  • Share on Facebook, Twitter, Email, NFC and much more.
  • Take photo functionality with face detection auto focus, steady mode, rule of thirds grid. Integrated into the phone as a Lens. The steady mode requires a device with a gyroscope. The face focus is enabled if the device supports focus at point. It also supports devices with a front facing camera.
  • Post edits from the Pictures Hub using the WP Rich Media extension.
  • Crop, rotate and flip also with predefined aspect ratios.
  • Multi-touch manipulation for Tilt Shift and other effects where multi-touch is meaningful.
  • The app can save edited pictures with advanced effects applied in full resolution even on a device with 256 MB RAM. Thus making it also possible to print the image or use it as desktop wallpaper.
  • Full Pictures Hub Extras integration.
  • The trial version includes the complete functionality and all the effects, only the save functionality is disabled.
  • Support for landscape and portrait orientation.
  • Effect list with dynamic previews and caching of the larger previews.
  • Flicking through the effects on the main page.
  • Setting for the maximum output size, JPEG quality and many more.
  • State preservation when the app is deactivated (tombstoning).
  • Localization for English, German, Japanese, Chinese, Russian, Dutch, French, Italian, Spanish, Portuguese and Portuguese (Brasil).








How it works
Some of the image processing algorithms that are used in the Pictures Lab app would normally be implemented as pixel shaders for Silverlight. The Windows Phone platform doesn't support custom pixel shaders at the moment, therefore all effects are implemented in C# and manipulate the WriteabeBitmap Pixels' in some way. How this works in detail was shown in my Coding4Fun articles I've written months ago. This is actually where Pictures Lab has its roots. The first article described all the necessary basics and two simple effects. The second part of this short Coding4Fun article series shows how to implement the basic tilt shift and vintage effects you can find in the Pictures Lab app. Yes, some parts are open source! Except the secret sauces I gotta keep for me that adds the final touch to the effects. I also wrote blog posts about some parts of the application that are surely interesting for other Windows Phone developers.
The Slider control that is used in the App was originally developed by Nokola and then adapted for Windows Phone and made bindable by Clint Rutkas and myself.

To be continued
The planned feature list for the next versions is already pretty long and I have some real diamonds on there. You can follow @PicturesLab on Twitter to get all the status updates. I'd also like to know what feature you want to see in a future version. Just write a comment.

Monday, September 20, 2010

Windows Phone Memory Constraints

The final Windows Phone Developer Tools have been released and the launch date is not far away. It's time to finalize the apps.
Windows Phone has some tough hardware requirements, but it's still a mobile platform with limited resources. In this blog post I'll describe how to determine the current memory usage, what the allowed maximum is to get your app approved for the Marketplace and other constraints a developer should be aware of.


Maximum memory usage
The Windows Phone hardware specifications requires that a device has 256 MB RAM or more. The allowed maximum memory an app can use is defined in the Windows Phone 7 Application Certification Requirements at point 5.2.5
The application must not exceed 90 MB of RAM usage. However, on devices that have more than 256 MB of memory, an application can exceed 90 MB of RAM usage.
One might now ask how to get this information at runtime. Fortunately there's the DeviceExtendedProperties class to obtain some device information at runtime. This class defines the GetValue and TryGetValue methods which expect a string key as parameter. The list of available property keys is defined here. Among other interesting properties like the DeviceUniqueId, it's possible to retrieve the DeviceTotalMemory, the ApplicationCurrentMemoryUsage and the ApplicationPeakMemoryUsage. The property keys are interpreted case-sensitive.
The application needs to define the device identity capability in the WMAppManifest.xml file in order to retrieve the DeviceUniqueId property, but it's not needed for the other keys like the ApplicationPeakMemoryUsage.

Here's the code to get the peak memory usage and the available total memory at runtime:

var timer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(2)};
timer.Tick += (s, e) =>
{
   var memuse = (long)DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage");
   var maxmem = (long)DeviceExtendedProperties.GetValue("DeviceTotalMemory");
   memuse /= 1024 * 1024;
   maxmem /= 1024 * 1024;
   MyTextBlock.Text = String.Format("Mem usage: {0} / {1} MB", memuse, maxmem);
};
timer.Start();

The timer checks the properties every two seconds and converts the bytes to MB. The values are then shown in a TextBlock. The peak memory is the most interesting since this value must not exceed 90 MB on a device with 256 MB. Also note that an empty application with two grids and a TextBlock already has a peak of 5 - 7 MB in the emulator or on a device.


PhoneApplicationPage.State limitation
The PhoneApplicationPage.State property is typically used to save transient state for tombstoning. The size of the State data is limited to 2 MB for a Page and 4 MB for the whole application. Be warned, if this limit is reached a not very descriptive exception is thrown. The message text is "The client who called IAccessControl::IsAccessPermitted was the trustee provided tot he method".
If more than 2 / 4 MB is needed to save transient data, the IsolatedStorage can be used. The applications IsolatedStorage is only limited by the device's flash storage size. The minimum requirement for Windows Phone is 8 GB. The available free isolated storage in bytes can be retrieved with the AvailableFreeSpace property of the IsolatedStorageFile class.

Tuesday, August 31, 2010

Rect and Point Extension Methods

I'm currently working on multiple Windows Phone projects and don't have much time for longer blog posts, but I just wanted to get this out.
For one of the projects I need to calculate some simple vector arithmetics like the Euclidean distance. I also need other properties of the Point and Rect structs that aren't built-in the Silverlight framework. As you might know I'm a huge fan of extension methods for extending built-in functionality (12). That's why I wrote a few extension methods for the Point and Rect structs that might come handy.

Rect
public static class RectExtensions
{   
   // Calculates the center point of this rectangle.
   public static Point Center(this Rect rect)
   {
      return new Point(rect.X + rect.Width * 0.5, rect.Y + rect.Height * 0.5);
   }

   // Tests if this rectangle intersects with the other.
   public static bool IntersectsWith(this Rect rect, Rect other)
   {
      // Test for separating axis
      if (other.Bottom < rect.Top || other.Right < rect.Left 
       || other.Top > rect.Bottom || other.Left > rect.Right)
      {
         return false;
      }
      return true;
   }
}

The usage should be pretty obvious.
Rect r = new Rect(0, 0, 200, 300);
Point center = r.Center();

bool isIntersecting = r.IntersectsWith(new Rect(500, 600, 100, 50));


Point
public static class PointExtensions
{
   // Calculates the distance vector of the points.
   public static Point Distance(this Point p1, Point p2)
   {
      return new Point(p1.X - p2.X, p1.Y - p2.Y);
   }

   // Calculates the length of the vector.
   public static double Length(this Point p)
   {
      return Math.Sqrt(p.X * p.X + p.Y * p.Y);
   }

   // Calculates the square length of the vector.
   public static double LengthSquare(this Point p)
   {
      return p.X * p.X + p.Y * p.Y;
   }
}

The squared length saves some cycles if this information is only needed for comparison.
Point p1 = new Point(200, 300);
Point p2 = new Point(400, 500);
Point distance = p1.Distance(p2);

double length = distance.Length();
double lengthSq = distance.LengthSquare();
length = Math.Sqrt(lengthSq);

Source Code
You can download the two C# files from here.

Tuesday, August 10, 2010

Coding4Fun - Part 1 of the Windows Phone Picture Effects App and Roadmap

My new Windows Phone 7 article for Microsoft's Coding4Fun site is live. It's the first part of a short series about the development of a Windows Phone 7 picture effects application called "PicFx". The first article will show how to create the base Windows Phone application and how to implement some basic effects. The source code is licensed under the Ms-PL and can be downloaded from the CodePlex site.
I'm already working on the second part of the series, which will explain how to implement advanced effects (the cool stuff) and other features. After this article I'll add more features and important effects, enhance the existing effects and release it as "Pictures Lab" on the Marketplace.

Video
The video below demonstrates the Coding4Fun PicFx application features and also shows how it can be used. It was recorded with the application running in the emulator.