private void InitWithCGImage(CGImage image)
{
int width, height;
CGBitmapContext bitmap = null;
bool hasAlpha;
CGImageAlphaInfo alphaInfo;
CGColorSpace colorSpace;
int bitsPerComponent, bytesPerRow;
CGBitmapFlags bitmapInfo;
bool premultiplied = false;
int bitsPerPixel = 0;
if (image == null) {
throw new ArgumentException (" image is invalid! " );
}
alphaInfo = image.AlphaInfo;
hasAlpha = ((alphaInfo == CGImageAlphaInfo.PremultipliedLast) || (alphaInfo == CGImageAlphaInfo.PremultipliedFirst) || (alphaInfo == CGImageAlphaInfo.Last) || (alphaInfo == CGImageAlphaInfo.First) ? true : false);
imageSize.Width = (int)image.Width;
imageSize.Height = (int)image.Height;
width = (int)image.Width;
height = (int)image.Height;
// Not sure yet if we need to keep the original image information
// before we change it internally. TODO look at what windows does
// and follow that.
bitmapInfo = image.BitmapInfo;
bitsPerComponent = (int)image.BitsPerComponent;
bitsPerPixel = (int)image.BitsPerPixel;
bytesPerRow = width * bitsPerPixel/bitsPerComponent;
int size = bytesPerRow * height;
colorSpace = image.ColorSpace;
// Right now internally we represent the images all the same
// I left the call here just in case we find that this is not
// possible. Read the comments for non alpha images.
if(colorSpace != null) {
if( hasAlpha ) {
premultiplied = true;
colorSpace = CGColorSpace.CreateDeviceRGB ();
bitsPerComponent = 8;
bitsPerPixel = 32;
bitmapInfo = CGBitmapFlags.PremultipliedLast;
}
else
{
// even for images without alpha we will internally
// represent them as RGB with alpha. There were problems
// if we do not do it this way and creating a bitmap context.
// The images were not drawing correctly and tearing. Also
// creating a Graphics to draw on was a nightmare. This
// should probably be looked into or maybe it is ok and we
// can continue representing internally with this representation
premultiplied = true;
colorSpace = CGColorSpace.CreateDeviceRGB ();
bitsPerComponent = 8;
bitsPerPixel = 32;
bitmapInfo = CGBitmapFlags.NoneSkipLast;
}
} else {
premultiplied = true;
colorSpace = CGColorSpace.CreateDeviceRGB ();
bitsPerComponent = 8;
bitsPerPixel = 32;
bitmapInfo = CGBitmapFlags.NoneSkipLast;
}
bytesPerRow = width * bitsPerPixel/bitsPerComponent;
size = bytesPerRow * height;
bitmapBlock = Marshal.AllocHGlobal (size);
bitmap = new CGBitmapContext (bitmapBlock,
width, height,
bitsPerComponent,
bytesPerRow,
colorSpace,
bitmapInfo);
bitmap.ClearRect (new CGRect (0,0,width,height));
// We need to flip the Y axis to go from right handed to lefted handed coordinate system
var transform = new CGAffineTransform(1, 0, 0, -1, 0, image.Height);
bitmap.ConcatCTM(transform);
bitmap.DrawImage (new CGRect (0, 0, image.Width, image.Height), image);
var provider = new CGDataProvider (bitmapBlock, size, true);
NativeCGImage = new CGImage (width, height, bitsPerComponent,
bitsPerPixel, bytesPerRow,
colorSpace,
bitmapInfo,
provider, null, true, image.RenderingIntent);
colorSpace.Dispose();
bitmap.Dispose();
}