Rotating a Bitmap in Mono for Android and MonoTouch

In a post last year, I wrote about a need I had to display a bitmap received from a web service but rotated by 90 degrees. This was for an Android application I was writing at the time using Eclipse and Java. As I recently stated, I’ve been looking at using C# to build iOS apps and decided to go the whole hog and checkout Mono for Android too. So I began by porting that application to Mono for Android which took around a week. Now I’ve nearly finished porting it to MonoTouch, the iOS equivalent. I can’t express how much I love the ability to use C# to write for these two platforms. Everyone associated with all things Mono should be congratulated for a terrific achievement, especially when you consider that even Microsoft are using Mono to write iOS apps now! Who’d have thunk it? :)

Anyway, for completeness I thought I would show the rotating bitmap code again but this time using C# code for the Android and iOS flavours of Mono. Hope it’s of use to someone out there.

Android:


// assume something hands us a bitmap
Bitmap myBitmap = GetImageFromWebService();

// get the width and height of the current view
Display d = WindowManager.DefaultDisplay;
int x = d.Width;
int y = d.Height;
	              
// scale it to fit the screen
Bitmap scaledBmp = Bitmap.CreateScaledBitmap(myBitmap, y, x, true);
	       
// create a matrix, rotate it anti-clockwise by 90 degrees
Matrix matrix = new Matrix();
matrix.PostRotate(-90);      
	       
// create a new rotated bitmap using the our original bitmap and the matrix measurements
Bitmap rotatedBmp = Bitmap.CreateBitmap(scaledBmp, 0, 0, scaledBmp.Width, scaledBmp.Height, matrix, true);    
	       
return rotatedBmp;

iOS:

	 

// assume something hands us a bitmap
UIImage myImg = GetImageFromWebService();
       
SizeF newSize = new SizeF(myImg.Size.Height, myImg.Size.Width);
	
UIGraphics.BeginImageContext(newSize);
CGContext ctx = UIGraphics.GetCurrentContext();
			
ctx.TranslateCTM(myImg.Size.Height, myImg.Size.Width); 
			
// scale
ctx.ScaleCTM(1f, -1f);
			
// rotate anti-clockwise
ctx.RotateCTM(1.57079633f);
			
// draw a new image with the same size
ctx.DrawImage(new RectangleF(0, 0, myImg.Size.Width, myImg.Size.Height), myImg.CGImage);
UIImage rotatedImage = UIGraphics.GetImageFromCurrentImageContext();
	
UIGraphics.EndImageContext();
		
return rotatedImage;

To be fair, the Android version is not that different from before (as you’d expect really) what with Java and C# being of similar syntax. The iOS version however is quite a bit different and perhaps a little bit more involved but it’s still fairly easy. You can experiment with the values passed to the various CTM (current transformation matrix) methods or change the size of the newly drawn image in the DrawImage method to see how they affect the resulting image display.

As for why I rewrote the Java based app in Mono C# well, for one C# is IMHO a nicer language than Java, and two, I extracted the business logic out into a separate assembly which is now shared between both the Android and iOS applications which means I only have to add new features or fix bugs in one place. It’s also been a lot easier and quicker to create the iOS version of the app than I’m sure it would have been if I had gone down the Objective-C route.

Advertisements
Rotating a Bitmap in Mono for Android and MonoTouch

Building iOS apps with C#

Learning Java in the context of the Android platform has been, and still is, an interesting ride but it’s also a time consuming one, and when you’re having to jump between platforms and languages it can often leave you a little confused as you sit and stare at the compiler’s helpful little underline squiggle telling you that what you’ve just written is nonsense even though you’re sure it’s right, until you realise you’re still in Java mode when you’re using Visual Studio and C#! Doh! :)

So the idea of learning yet another language, in this case Objective-C for iOS apps, worries me a little bit. Will my tiny brain be able to cope with all this information? On the one hand, it’s a new skill, what’s not to like? On the other, it’s yet more time I need to find in order to get proficient at it, and unlike Java, Objective-C is not that similar to C# so the mental leap is a little bit bigger. There is another way though that we can leverage our existing skill set and it’s called MonoTouch which together with the MonoDevelop IDE gives us a complete solution to writing applications for the iPhone and iPad using C# and after having played with it for a few days now I have nothing but praise for it. I was amazed at how quickly I managed to get a basic application running. I even imported some C# classes written using Visual Studio which compiled with no changes at all.

Let’s compare a snippet of Objective-C with C# to create and show an ActionSheet which is a kind of dialog that slides up from the bottom of the screen.

First the Objective-C version:


UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"hello world"
                                                         delegate:nil
                                                cancelButtonTitle:@"OK"
                                           destructiveButtonTitle:nil
					                            otherButtonTitles:nil];
[actionSheet showInView:[[self view] window]];

Now the C# version:


var actionSheet = new UIActionSheet("hello world", null, "OK", null, null);
actionSheet.ShowInView(this.View.Window):

Now its not a complex piece of code by any stretch, and maybe I’m biased but I definitely think the C# code is easier to read, write, and understand (although I do concede that specifying the parameter names inline, as the Objective-C version does, aids the reader) so given the choice it’s obvious which one I would prefer to write in. And from a business point of view if you’re a .Net development shop and your customers are now asking for iPhone applications then making the most of your in-house skills should definitely be factored into the decision process. When you consider that all the things you know and love about C# are still available to you such as LINQ, lambdas, events, and even the ability to utilise dual cores through the AsParallel method on collections, as a .Net developer you have to have a real damned good reason to go off and learn Objective-C because it’s going to be a good while until you’re as proficient in that language as the one you’re already used to. Having said that, as the examples show, you still use classes that are part of the iOS SDK so maybe the language should more accurately be called Objective-csharp instead! :)

Are there any drawbacks? Well, aside from still needing a Mac, from a single developer point of view the main negative is the cost. At 399 euros its not an impulse decision but for a business it is insignificant compared to the productivity gained from a language and IDE familiar to your development team. The one other possible negative is that Objective-C coders might give you a hard time for not doing “real” iOS development but that’d be their problem not yours. The good news is that the trial never expires so you can keep developing in it and writing apps for iOS for as long as you like but you can only ever run them on the simulator. Obviously, if you write something worth releasing then you’ll need to take the plunge but as it stands its a great way to get into iOS development without throwing away your existing skill set.

I’ll write up my experiences with MonoTouch as I learn more over time but right now I’m really impressed by it and can’t wait to dig deeper.

Building iOS apps with C#