IOS4 note 16 (3) UIImage and Graphics Contexts

UIImage and Graphics Contexts

The function UIGraphicsBeginImageContext creates a graphics context suitable for use as an image and makes it the current context. You then draw into this context to generate the image. When you’ve done that, you call UIGraphicsGetImageFromCurrentImageContext  to  turn  the context  into a UIImage, and  then UIGraphicsEndImageContext  to dismiss the context. Now you have a UIImage that you can display in a UIImageView or draw into some other graphics context. 

UIImage provides methods for drawing itself into the current context. We now know how to obtain an image context and make it the current context, so we can experiment with these methods. Here, I’ll draw two pictures of Mars side by side:

UIImage* mars = [UIImage imageNamed:@"Mars.png"];

CGSize sz = [mars size];

UIGraphicsBeginImageContext(CGSizeMake(sz.width*2, sz.height));

[mars drawAtPoint:CGPointMake(0,0)];

[mars drawAtPoint:CGPointMake(sz.width,0)];

UIImage* im = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

 

UIImageView* iv = [[UIImageView alloc] initWithImage:im];

[self.window addSubview: iv];

iv.center = self.window.center;

[iv release];

 

Additional UIImage methods let you scale an image into a desired rectangle as you draw, and specify the compositing (blend) mode whereby the image should combine with whatever is already present. To illustrate, I’ll create an image of Mars centered in another image of Mars that’s twice as large, using a blend mode:

UIImage* mars = [UIImage imageNamed:@"Mars.png"];

CGSize sz = [mars size];

UIGraphicsBeginImageContext(CGSizeMake(sz.width*2, sz.height*2));

[mars drawInRect:CGRectMake(0,0,sz.width*2,sz.height*2)];

[mars drawInRect:CGRectMake(sz.width/2.0, sz.height/2.0, sz.width, sz.height)

           blendMode:kCGBlendModeMultiply alpha:1.0];

UIImage* im = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

 

There is no UIImage method for specifying the source rectangle — that is, for specifying that you want to extract a smaller region of the original image. You can work around this by specifying a smaller graphics context and positioning the image drawing so that the desired region falls into it. For example, to obtain an image of the right half of Mars, you’d make your graphics context half  the width of  the mars  image, and  then draw mars shifted left, so that only its right half intersects the graphics context. There is no harm in doing this, and it’s a perfectly standard device; the left half of mars simply isn’t drawn:

UIImage* mars = [UIImage imageNamed:@"Mars.png"];

CGSize sz = [mars size];

UIGraphicsBeginImageContext(CGSizeMake(sz.width/2.0, sz.height));

[mars drawAtPoint:CGPointMake(-sz.width/2.0, 0)];

UIImage* im = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

 

On a double-resolution device,the use of  UIGraphicsBeginImageContext  leads  to an undesirable result. The code works, and the image mars will of course be the double-resolution version if there is one but the image ultimately being generated, im, is single-resolution (its scale is 1.0). To generate a double-resolution image as our final output, we must call UIGraphicsBeginImageContextWithOptions  instead  of  UIGraphicsBeginImageContext. The third parameter is the scale; if it is 0.0, the correct scale for the current device will be assigned for us. This function was introduced in iOS 4.0, so to run without crashing on an earlier system you’d need to test for its existence:

if (&UIGraphicsBeginImageContextWithOptions)

    UIGraphicsBeginImageContextWithOptions(sz, NO, 0.0);

else

    UIGraphicsBeginImageContext(sz);

 

 

你可能感兴趣的:(IOS4 note 16 (3) UIImage and Graphics Contexts)