CGLayers are great for drawing - especially when things need to be drawn over and over again. Converting a CGLayer to a UIImage is another story, though. NetSketch uses CGLayers for the drawing canvas, but converts them to UIImages when you go to upload your drawing or email it to a friend. The code below shows how it’s done. The CGLayer is drawn into a bitmap CGContext of the same size, and then a CGImage is created around the CGContext. The CGImage can be turned into a UIImage, and you’re done!
Be sure to leave a comment if you find this function useful!
- UIImage* UIImageFromLayer(CGLayerRef layer)
- {
- // Create the bitmap context
- CGContextRef bitmapContext = NULL;
- void * bitmapData;
- int bitmapByteCount;
- int bitmapBytesPerRow;
- CGSize size = CGLayerGetSize(layer);
- // Declare the number of bytes per row. Each pixel in the bitmap in this
- // example is represented by 4 bytes; 8 bits each of red, green, blue, and
- // alpha.
- bitmapBytesPerRow = (size.width * 4);
- bitmapByteCount = (bitmapBytesPerRow * size.height);
- // Allocate memory for image data. This is the destination in memory
- // where any drawing to the bitmap context will be rendered.
- bitmapData = malloc( bitmapByteCount );
- if (bitmapData == NULL)
- {
- return nil;
- }
- // Create the bitmap context. We want pre-multiplied ARGB, 8-bits
- // per component. Regardless of what the source image format is
- // (CMYK, Grayscale, and so on) it will be converted over to the format
- // specified here by CGBitmapContextCreate.
- bitmapContext = CGBitmapContextCreate (bitmapData, size.width, size.height,8,bitmapBytesPerRow,
- CGColorSpaceCreateDeviceRGB(),kCGImageAlphaNoneSkipFirst);
- if (bitmapContext == NULL)
- // error creating context
- return nil;
- CGContextScaleCTM(bitmapContext, 1, -1);
- CGContextTranslateCTM(bitmapContext, 0, -size.height);
- // Draw the image to the bitmap context. Once we draw, the memory
- // allocated for the context for rendering will then contain the
- // raw image data in the specified color space.
- CGContextDrawLayerAtPoint(bitmapContext, CGPointZero, layer);
- CGImageRef img = CGBitmapContextCreateImage(bitmapContext);
- UIImage* ui_img = [UIImage imageWithCGImage: img];
- CGImageRelease(img);
- CGContextRelease(bitmapContext);
- free(bitmapData);
- return ui_img;
- }
总体意思是:把CGLayer画在新建的CGContext上,然后再转换为UIImage。我的方法会更简单。
- UIImage* UIImageFromLayer(CGLayerRef layer)
- {
- CGContextRef ctx = CGLayerGetContext(layer);
- CGImageRef img = CGBitmapContextCreateImage(bitmapContext);
- UIImage* ui_img = [UIImage imageWithCGImage: img];
- }