Difference between revisions of "An iOS 7 Graphics Tutorial using Core Graphics and Core Image"

From Techotopia
Jump to: navigation, search
m (Text replacement - "<google>BUY_IOS7</google>" to "<htmlet>ios9_upgrade</htmlet>")
m (Text replacement - "<table border="0" cellspacing="0">" to "<table border="0" cellspacing="0" width="100%">")
 
(One intermediate revision by the same user not shown)
(No difference)

Latest revision as of 19:58, 27 October 2016

PreviousTable of ContentsNext
Drawing iOS 7 2D Graphics with Core GraphicsBasic iOS 7 Animation using Core Animation


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


As previously discussed in Drawing iOS 7 2D Graphics with Core Graphics, the Quartz 2D API is the primary mechanism by which 2D drawing operations are performed within iOS applications. Having provided an overview of Quartz 2D as it pertains to iOS development in that chapter, the focus of this chapter is to provide a tutorial that provides examples of how 2D drawing is performed. If you are new to Quartz 2D and have not yet read Drawing iOS 7 2D Graphics with Core Graphics it is recommended that you do so now before embarking on this tutorial.


Contents


The iOS Drawing Example Application

The application created in this tutorial will contain a subclassed UIView component within which the drawRect method will be overridden and used to perform a variety of 2D drawing operations.

Creating the New Project

Create the new project by launching the Xcode development environment and selecting the option to create a new project. When prompted to select a template for the application, choose the Single View Application option and name the project and class prefix Draw2D with the device configuration set to either iPad or iPhone.


Creating the UIView Subclass

In order to draw graphics on the view it is necessary to create a subclass of the UIView object and override the drawRect method. In the project navigator panel located on the left hand side of the main Xcode window Ctrl-click on the Draw2D folder entry and select New File… from the resulting menu. In the New File window, select the Objective-C class icon and click Next. On the subsequent options screen, change the Subclass of: menu to UIView and the class name to Draw2D. Click Next and on the final screen click on the Create button.

Select the Main.storyboard file and select the UIView component in either the view controller canvas or the document outline panel. Display the Identity Inspector (View -> Utilities -> Show Identity Inspector) and change the Class setting from UIView to our new class named Draw2D:


Changing the class of a view instance in Xcode 5

Figure 52-1


Locating the drawRect Method in the UIView Subclass

Now that we have subclassed our application’s UIView the next step is to implement the drawRect method in this subclass. Fortunately Xcode has already created a template of this method for us. To locate this method, select the Draw2D.m file in the project navigator panel of the main Xcode project window and scroll down the file contents in the edit pane until the drawRect method comes into view (it should be located immediately beneath the initWithFrame method). Having located the method in the file, remove the comment markers (/* and */) within which it is currently encapsulated:

#import "Draw2D.h"

@implementation Draw2D

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
@end

In the remainder of this tutorial we will modify the code in the drawRect method to perform a variety of different drawing operations.

Drawing a Line

In order to draw a line on a device screen using Quartz 2D we first need to obtain the graphics context for the view:

CGContextRef context = UIGraphicsGetCurrentContext();

Once the context has been obtained, the width of the line we plan to draw needs to be specified:

CGContextSetLineWidth(context, 2.0);

Next, we need to create a color reference. We can do this by specifying the RGBA components of the required color (in this case opaque blue):

CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); 
CGFloat components[] = {0.0, 0.0, 1.0, 1.0};
CGColorRef color = CGColorCreate(colorspace, components);

Using the color reference and the context we can now specify that the color is to be used when drawing the line:

CGContextSetStrokeColorWithColor(context, color);

The next step is to move to the start point of the line that is going to be drawn:

CGContextMoveToPoint(context, 30, 30);

The above line of code indicates that the start point for the line is the top left hand corner of the device display. We now need to specify the end point of the line, in this case 300, 400:

CGContextAddLineToPoint(context, 300, 400);

Having defined the line width, color and path, we are ready to draw the line and release the colorspace and color reference objects:

CGContextStrokePath(context);
CGColorSpaceRelease(colorspace);
CGColorRelease(color);

Bringing this all together gives us a drawRect method that reads as follows:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 2.0);
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CGFloat components[] = {0.0, 0.0, 1.0, 1.0};
    CGColorRef color = CGColorCreate(colorspace, components);
    CGContextSetStrokeColorWithColor(context, color);
    CGContextMoveToPoint(context, 30, 30);
    CGContextAddLineToPoint(context, 300, 400);
    CGContextStrokePath(context);
    CGColorSpaceRelease(colorspace);
    CGColorRelease(color);
}

When compiled and run, the application should display as illustrated in Figure 52-2:


A line drawn with Core Graphics on iOS 7

Figure 52-2


Note that in the above example we manually created the colorspace and color reference. As described in Drawing iOS 7 2D Graphics with Core Graphics colors can also be created using the UIColor class. For example, the same result as outlined above can be achieved with fewer lines of code as follows:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, [UIColor
       blueColor].CGColor);
    CGContextMoveToPoint(context, 30, 30);
    CGContextAddLineToPoint(context, 300, 400);
    CGContextStrokePath(context);
}

Drawing Paths

As you may have noticed, in the above example we draw a single line by essentially defining the path between two points. Defining a path that comprises multiple points allows us to draw using a sequence of straight lines all connected to each other using repeated calls to the CGContextAddLineToPoint() function. Non-straight lines may also be added to a shape using calls to, for example, the CGContextAddArc() function.

The following code, for example, draws a diamond shape:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, 
      [UIColor blueColor].CGColor);
    CGContextMoveToPoint(context, 100, 100);
    CGContextAddLineToPoint(context, 150, 150);
    CGContextAddLineToPoint(context, 100, 200);
    CGContextAddLineToPoint(context, 50, 150);
    CGContextAddLineToPoint(context, 100, 100);
    CGContextStrokePath(context);
}

When executed, the above code should produce output that appears as shown in Figure 52 3:


An iOS Core Graphics Path drawing

Figure 52-3


Drawing a Rectangle

Rectangles are drawn in much the same way as any other path is drawn, with the exception that the path is defined by specifying the x and y co-ordinates of the top left hand corner of the rectangle together with the rectangle’s height and width. These dimensions are stored in a CGRect structure and passed through as an argument to the CGContextAddRect function:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 4.0);
    CGContextSetStrokeColorWithColor(context, 
     [UIColor blueColor].CGColor);
    CGRect rectangle = CGRectMake(60,170,200,80);
    CGContextAddRect(context, rectangle);
    CGContextStrokePath(context);
}

The above code will result in the following display when compiled and executed:


An iOS Core Graphics Rectangle

Figure 52-4


Drawing an Ellipse or Circle

Circles and ellipses are drawn by defining the rectangular area into which the shape must fit and then calling the CGContextAddEllipseInRect() function:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 4.0);
    CGContextSetStrokeColorWithColor(context, 
      [UIColor blueColor].CGColor);
    CGRect rectangle = CGRectMake(60,170,200,80);
    CGContextAddEllipseInRect(context, rectangle);
    CGContextStrokePath(context);
}

When compiled, the above code will produce the following graphics:


An iOS 7 Core Graphics Ellipse

Figure 52-5


In order to draw a circle simply define a rectangle with equal length sides (a square in other words).

Filling a Path with a Color

A path may be filled with a color using a variety of Quartz 2D API functions. Rectangular and elliptical paths may be filled using the CGContextFillRect() and CGContextFillEllipse() functions respectively. Similarly, a path may be filled using the CGContextFillPath() function. Prior to executing a fill operation, the fill color must be specified using the CGContextSetFillColorWithColor() function.

The following example defines a path and then fills it with the color red:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextMoveToPoint(context, 100, 100);
    CGContextAddLineToPoint(context, 150, 150);     
    CGContextAddLineToPoint(context, 100, 200);
    CGContextAddLineToPoint(context, 50, 150);
    CGContextAddLineToPoint(context, 100, 100);
    CGContextSetFillColorWithColor(context, 
      [UIColor redColor].CGColor);
    CGContextFillPath(context);
}

The above code produces the following graphics on the device or simulator display when executed:


A filled path drawn using iOS 7 Core Graphics

Figure 52-6


The following code draws a rectangle with a blue border and then once again fills the rectangular space with red:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 4.0);
    CGContextSetStrokeColorWithColor(context, 
      [UIColor blueColor].CGColor);
    CGRect rectangle = CGRectMake(60,170,200,80);
    CGContextAddRect(context, rectangle);
    CGContextStrokePath(context);
    CGContextSetFillColorWithColor(context, 
      [UIColor redColor].CGColor);
    CGContextFillRect(context, rectangle);
}

When added to the example application, the resulting display should appear as follows:


An iOS 7 Core Graphics filled and outlined rectangle

Figure 52-7

Drawing an Arc

An arc may be drawn by specifying two tangent points and a radius using the CGContextAddArcToPoint() function, for example:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 4.0);
    CGContextSetStrokeColorWithColor(context, 
      [UIColor blueColor].CGColor);
    CGContextMoveToPoint(context, 100, 100);
    CGContextAddArcToPoint(context, 100,200, 300,200, 100);
    CGContextStrokePath(context);
}

The above code will result in the following graphics output:


An iOS 7 Core Graphics Arc

Figure 52-8


Drawing a Cubic Bézier Curve

A cubic Bézier curve may be drawn by moving to a start point and then passing two control points and an end point through to the CGContextAddCurveToPoint() function:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 4.0);
    CGContextSetStrokeColorWithColor(context, 
       [UIColor blueColor].CGColor);
    CGContextMoveToPoint(context, 10, 10);
    CGContextAddCurveToPoint(context, 0, 50, 300, 250, 300, 400);
    CGContextStrokePath(context);
} 

The above code will cause the curve illustrated in Figure 52 9 to be drawn when compiled and executed in our example application:

An iOS 7 Core Graphics Cubic Bézier Curve

Figure 52-9


Drawing a Quadratic Bézier Curve

A quadratic Bézier curve is drawn using the CGContextAddQuadCurveToPoint() function, providing a control and end point as arguments having first moved to the start point:

- (void)drawRect:(CGRect)rect {
   CGContextRef context = UIGraphicsGetCurrentContext();
   CGContextSetLineWidth(context, 4.0);
   CGContextSetStrokeColorWithColor(context, 
     [UIColor blueColor].CGColor);
   CGContextMoveToPoint(context, 10, 200);
   CGContextAddQuadCurveToPoint(context, 150, 10, 300, 200);
   CGContextStrokePath(context);
}

The above code, when executed, will display a curve that appears as illustrated in the following figure:


An iOS 7 Core Graphics Quadratic Bézier Curve

Figure 52-10

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

Dashed Line Drawing

So far in this chapter we have performed all our drawing with a solid line. Quartz also provides support for drawing dashed lines. This is achieved via the Quartz CGContextSetLineDash() function which takes as its arguments the following:

  • context – The graphics context of the view on which the drawing is to take place
  • phase - A floating point value that specifies how far into the dash pattern the line starts
  • lengths – An array containing values for the lengths of the painted and unpainted sections of the line. For example an array containing 5 and 6 would cycle through 5 painted unit spaces followed 6 unpainted unit spaces.
  • count – A count of the number of items in the lengths array

For example, a [2,6,4,2] lengths array applied to a curve drawing of line thickness 5.0 will appear as follows:


An iOS 7 Core Graphics dashed line

Figure 52-11


The corresponding drawRect code that drew the above line reads as follows:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 20.0);
    CGContextSetStrokeColorWithColor(context, 
       [UIColor blueColor].CGColor);
    CGFloat dashArray[] = {2,6,4,2};
    CGContextSetLineDash(context, 3, dashArray, 4);
    CGContextMoveToPoint(context, 10, 200);
    CGContextAddQuadCurveToPoint(context, 150, 10, 300, 200);
    CGContextStrokePath(context);
}

Drawing Shadows

In addition to drawing shapes, Core Graphics can also be used to create shadow effects. This is achieved using the CGContextSetShadow function, passing through a graphics context, offset values for the position of the shadow relative to the shape for which the shadow is being drawn and a value specifying the degree of blurring required for the shadow effect. Colored shadows may similarly be created using the CGContextSetShadowWithColor function which takes an additional argument in the form of a CGColor object.

The following code, for example, draws an ellipse with a shadow:

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGSize  myShadowOffset = CGSizeMake (-10,  15);

    CGContextSaveGState(context);

    CGContextSetShadow (context, myShadowOffset, 5);

    CGContextSetLineWidth(context, 4.0);
    CGContextSetStrokeColorWithColor(context,
      [UIColor blueColor].CGColor);
    CGRect rectangle = CGRectMake(60,170,200,80);
    CGContextAddEllipseInRect(context, rectangle);
    CGContextStrokePath(context);
    CGContextRestoreGState(context);
}

When executed, the above code will produce the effect illustrated in Figure 52-12:


A shadow effect using iOS 7 Core Graphics

Figure 52-12


The color of the shadow could be changed, for the sake of an example, to red by calling CGContextSetShadowWithColor instead of CGContextSetShadow as follows:

CGContextSetShadowWithColor(context, myShadowOffset, 5, [UIColor redColor].CGColor);

Drawing Gradients

Gradients are implemented using the Core Graphics CGGradient class which provides support for linear, radial and axial gradients. Use of the CGGradient class essentially involves the specification of two or more colors together with a set of location values. The location values are used to indicate the points at which the gradient should switch from one color to another as the gradient is drawn along an axis line where 0.0 represents the start of the axis and 1.0 the end point. Assume, for the purposes of an example, that you wish to create a gradient that transitions through three different colors along the gradient axis with each color being given an equal amount of space within the gradient. In this situation, three locations would be specified. The first would be 0.0 to represent the start of the gradient. Two more locations would then need to be specified for the transition points to the remaining colors. In order to equally divide the axis amongst the colors these would need to be set to 0.3333 and 0.6666 respectively.

Having configured a CGGraident instance, a linear gradient is then drawn via a call to the CGContentDrawLinearGradient function, passing through the colors, locations and start and end points as arguments.

The following code, for example, draws a linear gradient using four colors with four equally spaced locations:

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGGradientRef gradient;
    CGColorSpaceRef colorspace;
    CGFloat locations[4] = { 0.0, 0.25, 0.5, 0.75 };

    NSArray *colors = @[(id)[UIColor redColor].CGColor, 
                        (id)[UIColor greenColor].CGColor,
                        (id)[UIColor blueColor].CGColor, 
                        (id)[UIColor yellowColor].CGColor];

    colorspace = CGColorSpaceCreateDeviceRGB();

    gradient = CGGradientCreateWithColors(colorspace, 
                  (CFArrayRef)colors, locations);

    CGPoint startPoint, endPoint;
    startPoint.x = 0.0;
    startPoint.y = 0.0;

    endPoint.x = 500;
    endPoint.y = 500;

    CGContextDrawLinearGradient(context, gradient, 
               startPoint, endPoint, 0); 
}  

When executed, the above code will generate the gradient shown in Figure 52-13:


An iOS 7 Core Graphics linear gradient

Figure 52-13


Radial gradients involve drawing a gradient between two circles. When the circles are positioned apart from each other and given different sizes a conical effect is achieved as shown in Figure 52-14:


A code drawn using iOS 7 Core Graphics gradients

Figure 52-14


The code to draw the above radial gradient sets up the colors and locations for the gradient before declaring the center points and radius values for two circles. The gradient is then drawn via a call to the CGContextDrawRadialGradient function:

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGGradientRef gradient;
    CGColorSpaceRef colorspace;
    CGFloat locations[3] = { 0.0, 0.5, 1.0 };

    NSArray *colors = @[(id)[UIColor redColor].CGColor, 
                        (id)[UIColor greenColor].CGColor,
                        (id)[UIColor cyanColor].CGColor];

    colorspace = CGColorSpaceCreateDeviceRGB();

    gradient = CGGradientCreateWithColors(colorspace, 
           (CFArrayRef)colors, locations);

    CGPoint startPoint, endPoint;
    CGFloat startRadius, endRadius;

    startPoint.x = 100;
    startPoint.y = 100;
    endPoint.x = 200;
    endPoint.y = 200;
    startRadius = 10;
    endRadius = 75;

    CGContextDrawRadialGradient(context, gradient, startPoint,
                         startRadius, endPoint, endRadius, 0);
}

Interesting effects may also be created by assigning a radius of 0 to the starting point circle and positioning it within the circumference of the end point circle:

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGGradientRef gradient;
    CGColorSpaceRef colorspace;
    CGFloat locations[2] = { 0.0, 1.0};

    NSArray *colors = @[(id)[UIColor whiteColor].CGColor, 
                        (id)[UIColor blueColor].CGColor];

    colorspace = CGColorSpaceCreateDeviceRGB();

    gradient = CGGradientCreateWithColors(colorspace, 
            (CFArrayRef)colors, locations);

    CGPoint startPoint, endPoint;
    CGFloat startRadius, endRadius;
    startPoint.x = 180;
    startPoint.y = 180;
    endPoint.x = 200;
    endPoint.y = 200;
    startRadius = 0;
    endRadius = 75;

    CGContextDrawRadialGradient (context, gradient, startPoint,
                         startRadius, endPoint, endRadius,
                         0);
}


When executed, the above code creates the appearance of light reflecting on the surface of a shiny blue sphere:


A glossy reflective sphere drawn with core graphics

Figure 52-15


Drawing an Image into a Graphics Context

An image may be drawn into a graphics context either by specifying the coordinates of the top left hand corner of the image (in which case the image will appear full size) or resized so that it fits into a specified rectangular area. Before we can display an image in our example application, however, that image must first be added to the project resources.

Begin by locating the desired image using the Finder and then drag and drop that image onto the Supporting Files category of the project navigator panel of the Xcode main project window.

The following example drawRect method code displays the image in a file named tree.jpg full size located at 0, 0:

- (void)drawRect:(CGRect)rect {
   UIImage *myImage = [UIImage imageNamed:@"tree.jpg"];
   CGPoint imagePoint = CGPointMake(0, 0);
   [myImage drawAtPoint:imagePoint];
}

As is evident when the application is run, the size of the image far exceeds the available screen size:


An unscaled image

Figure 52-16


Using the drawInRect method of the UIImage object, however, we can scale the image to fit better on the screen. In this instance it is useful to identify the screen size since this changes depending on the device on which the application is running. This can be achieved using the mainScreen and bounds methods of the UIScreen class. The mainScreen method returns another UIScreen object representing the device display. Calling the bounds method of that object returns the dimensions of the display in the form of a CGRect object:

- (void)drawRect:(CGRect)rect {
    UIImage *myImage = [UIImage imageNamed:@"tree.jpg"];
    CGRect imageRect =[[UIScreen mainScreen] bounds];
    [myImage drawInRect:imageRect];
}

This time, the entire image fits comfortably on the screen:


A scaled image

Figure 52-17


Image Filtering with the Core Image Framework

Having covered the concept of displaying images within an iOS application, now is a good time to provide a basic overview of the Core Image Framework.

Core Image was introduced with iOS 5 and provides a mechanism for filtering and manipulating still images and videos. Included with Core Image is a wide range of different filters together with the ability to build custom filters to meet specific requirements. Examples of filters that may be applied include cropping, color effects, blurring, warping, transformations and gradients. A full listing of filters is available in Apple’s Core Image Filter Reference document which is located in the iOS Developer portal.

A CIImage object is typically initialized with a reference to the image to be manipulated. A CIFilter object is then created and configured with the type of filtering to be performed, together with any input parameters required by that filter. The CIFilter object is then instructed to perform the operation and the modified image is subsequently returned in the form of a CIImage object. The application’s CIContext reference may then be used to render the image for display to the user.

By way of an example of Core Image in action we will modify the drawRect method of our Draw2D example application to render the previously displayed image in a sepia tone using the CISepiaTone filter. The first step, however, is to add the CoreImage framework to the project. This is achieved by selecting the Draw2D target at the top of the project navigator and then selecting the Build Phases tab in the main panel. Unfold the Link Binary with Libraries section of the panel, click on the + button and locate and add the CoreImage.framework library from the resulting list.

Having added the framework, select the Draw2D.m file and modify drawRect as follows:

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    UIImage *myimage = [UIImage imageNamed:@"tree.jpg"];
    CIImage *cimage = [[CIImage alloc] initWithImage:myimage];

    CIFilter *sepiaFilter = [CIFilter filterWithName:@"CISepiaTone"];
    [sepiaFilter setDefaults];
    [sepiaFilter setValue:cimage forKey:@"inputImage"];
    [sepiaFilter setValue:[NSNumber numberWithFloat:0.8f]
         forKey:@"inputIntensity"];

    CIImage *image = [sepiaFilter outputImage];
    CIContext *context = [CIContext contextWithOptions: nil];
    CGImageRef cgImage = [context createCGImage: 
          image fromRect: image.extent];
    UIImage *resultUIImage = [UIImage imageWithCGImage: cgImage];

    CGRect imageRect =[[UIScreen mainScreen] bounds];
    [resultUIImage drawInRect:imageRect];
}

The method begins by loading the image .jpg file used in the previous section of this chapter. Since Core Image works on CIImage objects it is then necessary to convert the UIImage to a CIImage. Next a new CIFilter object is created and initialized with the CISepiaTone filter. The filter is then set to the default settings before being configured with the input image (in this case our cimage object) and the value of intensity of the filter (0.8).

With the filter object configured, its outputFile method is called to perform the manipulation and the resulting modified image assigned to a new CImage object. The CIContext reference for the application is then obtained and used to convert the CImage object to a CGImageRef object. This, in turn, is converted to a UIImage object which is then displayed to the user using the object’s drawInRect method. When compiled and run the image will appear in a sepia tone.

Summary

By subclassing the UIView class and overriding the drawRect method a variety of 2D graphics drawing functions may be performed on the view canvas. In this chapter we have explored some of the graphics drawing capabilities of Quartz 2D to draw a variety of line types and paths and to present images on the iOS device screen.

Introduced in iOS 5, the Core Image framework is designed specifically for the filtering and manipulation of images and video. In this chapter we have provided a brief overview of Core Image and worked through a simple example that applied a sepia tone filter to an image.


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


PreviousTable of ContentsNext
Drawing iOS 7 2D Graphics with Core GraphicsBasic iOS 7 Animation using Core Animation