Monday, 5 October 2009

MonoTouch screen capture in c# code

In a previous post I said that if you capture a screenshot of your application's final 'state' (say in WillTerminate) and save it as Default.png then it would be used as the 'splash screen' next time the application starts (the built-in iPhone apps like Mail seem to do this by zooming in/out with a screen capture of their last state).

The code below takes a screenshot, and was supposed to overwrite the Default.png you have in your MonoTouch application root (eg. iSOFlair.app/) and become the new splash screen. In order to 'test' this theory I had to write the code below and place it in UIViewController subclasses that I wanted to 'capture'.

Anyway, here's the code... not sure what other uses it might have?
/// <summary>
/// Capture a copy of the current View and:
/// * re-display in a UIImage control
/// * save to the Photos collection
/// * save to disk in the application's Documents folder
/// </summary>
public void ScreenCapture()
{
var documentsDirectory = Environment.GetFolderPath
(Environment.SpecialFolder.Personal);

Console.WriteLine("start capture of frame: " + this.View.Frame.Size);
UIGraphics.BeginImageContext(View.Frame.Size);
var ctx = UIGraphics.GetCurrentContext();
if (ctx != null)
{
View.Layer.RenderInContext(ctx);
UIImage img = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();

// Set to display in a UIImage control _on_ the view
imageLogo.Image = img;

// Save to Photos
img.SaveToPhotosAlbum(
(sender, args)=>{Console.WriteLine("image saved to Photos");}
);

// Save to application's Documents folder
string png = Path.Combine (documentsDirectory, "Screenshot.png");
// HACK: overwrite the splash screen. iSOFlair is the application name
//string png = Path.Combine (documentsDirectory, "../iSOFlair.app/Default.png");

NSData imgData = img.AsPNG();
NSError err = null;
if (imgData.Save(png, false, out err))
{
Console.WriteLine("saved as " + png);
} else {
Console.WriteLine("NOT saved as" + png +
" because" + err.LocalizedDescription);
}
}
else
{
Console.WriteLine("ctx null - doesn't seem to happen");
}
}
Now your MonoTouch iPhone app would appear to "startup" much faster :) There is still a bit of a trick with the View.Frame.Size - doesn't take the status bar into account - which I will try to fix up in future. UPDATE: Tested in Simulator - works fine - but doesn't appear to work on the Device :-(.

Here is a useful ObjectiveC image tricks post that was helpful.

p.s. for those who don't already know - as a user you can always take a screen capture of the current display by pressing the Home and Power buttons at the same time... a new file will be created in your Photos : Camera Roll.

1 comment:

  1. I get an error when trying to use SaveToPhotosAlbum form the UIImage Class. An suggestions?

    I don't even need to take a Screen Shot just trying to save an Image to the Photot Albums.

    This is the error:
    malloc: *** error for object 0x48e0000: pointer being freed was not allocated
    *** set a breakpoint in malloc_error_break to debug

    ReplyDelete