Heres a method that works well:
public async Task<byte[]> RotateImage(UIImage image, float amount)
{
UIImage imageToReturn = null;
float radians = -1 * ((float)(amount * Math.PI) / 180);
bool isLandscape = false;
var x = image.Size.Width / 2;
var y = image.Size.Height / 2;
//https://stackoverflow.com/a/8536553
CGAffineTransform transform = new CGAffineTransform((nfloat)Math.Cos(radians), (nfloat)Math.Sin(radians), -(nfloat)Math.Sin(radians), (nfloat)Math.Cos(radians), (nfloat)(x - x * Math.Cos(radians)) + (nfloat)(y * Math.Sin(radians)), (nfloat)(y - x * Math.Sin(radians) - y * Math.Cos(radians)));
var diff = (image.Size.Height - image.Size.Width) / 2;
bool translateWidthAndHeight = false;
if (amount == 90)
{
translateWidthAndHeight = true;
transform.Translate(diff, -diff);
}
else if (amount == 180)
{
//Transform.Translate(image.Size.Width, -image.Size.Height);
}
else if (amount == 270)
{
translateWidthAndHeight = true;
transform.Translate(diff, -diff);
}
else if (amount == 360)
{
}
if (translateWidthAndHeight)
{
//now draw image
using (var context = new CGBitmapContext(IntPtr.Zero,
(int)image.Size.Height,
(int)image.Size.Width,
image.CGImage.BitsPerComponent,
image.CGImage.BitsPerComponent * (int)image.Size.Width,
image.CGImage.ColorSpace,
image.CGImage.BitmapInfo))
{
context.ConcatCTM(transform);
context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)image.Size.Width, (float)image.Size.Height)), image.CGImage);
using (var imageRef = context.ToImage())
{
imageToReturn = new UIImage(imageRef);
}
}
}
else
{
//now draw image
using (var context = new CGBitmapContext(IntPtr.Zero,
(int)image.Size.Width,
(int)image.Size.Height,
image.CGImage.BitsPerComponent,
image.CGImage.BitsPerComponent * (int)image.Size.Height,
image.CGImage.ColorSpace,
image.CGImage.BitmapInfo))
{
context.ConcatCTM(transform);
context.DrawImage(new RectangleF(PointF.Empty, new SizeF((float)image.Size.Width, (float)image.Size.Height)), image.CGImage);
using (var imageRef = context.ToImage())
{
imageToReturn = new UIImage(imageRef);
}
}
}
using (NSData imageData = imageToReturn.AsJPEG())
{
Byte[] byteArray = new Byte[imageData.Length];
System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, byteArray, 0, Convert.ToInt32(imageData.Length));
return byteArray;
}
}