CoreGraphics for high-performance pixel-level rendering

Refresh frame by frame with CADisplayLink

CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget: self 
                                                         selector: @selector(update)];
[displayLink addToRunLoop: NSRunLoop.mainRunLoop 
                  forMode: NSDefaultRunLoopMode];

In the refresh method, call setNeedsDisplay of the rendered UIView

- (void)update {
    [self.vv setNeedsDisplay];
}

Under the rendered UIView subclass, inherit drawLayer

// drawRect 也记得写上,否则失效
- (void)drawRect:(CGRect)rect {
    [super drawRect: rect];
}

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
    CGContextClearRect(ctx, CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height));
    CGContextSaveGState(ctx);
    const int width = 320;
    const int height = 640;
    CGRect drawRect = CGRectMake(0, 0, width, height);
    CGContextTranslateCTM(ctx, 0, self.bounds.size.height);
    CGContextScaleCTM(ctx, self.bounds.size.width / width, -self.bounds.size.height / height); 
    uint32_t pixels[width * height] = { 0 };
    for (size_t i = 0; i < width * height; ++i) {
        pixels[height][width] = 0xffffffff;
    }
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pixels,
                                                 width,
                                                 height,
                                                 8,
                                                 width * 4,
                                                 colorSpace,
                                                 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
    CGColorSpaceRelease(colorSpace);
    CGImageRef imageRef = CGBitmapContextCreateImage(context);
    CGContextRelease(context);
    CGContextDrawImage(ctx, drawRect, imageRef);
    CGContextRestoreGState(ctx);
}

○ Remember to inherit drawRect

When we draw CALayer, we need to use the relevant information of UIView, which is stored in CGContextRef, and this information can only be used drawRectafter .

That is to say, after UIView calls drawRect, it will further call drawLayer. Therefore, when inheriting UIView, you must inherit and implement drawRect, so that drawLayer inheritance will be called.

○ CGContextClearRect

Used to clear the information drawn in the rectangle.

○ CGContextSaveGState/CGContextRestoreGState

Save and restore the context, called at the beginning and end of drawing a layer. to avoid breaking previous context.

○ CGContextTranslateCTM

The function of this function is to translate the drawing context along the x-axis and y-axis by the specified distance.

In this example, why is CGContextTranslateCTM called like this:

`CGContextTranslateCTM(ctx, 0, self.bounds.size.height);` 

This CGContextScaleCTMcan .

CGContextTranslateCTM is used to set the starting area of ​​screen drawing, which is used here (0, self.bounds.size.height)to set the starting area of ​​drawing at the bottom left of the screen.

○ CGContextScaleCTM

If you follow the setting of the previous line of code, the drawn area is obviously "out of the screen". So a second function is needed CGContextScaleCTM, and you can see that the function is called like this:

CGContextScaleCTM(ctx, self.bounds.size.width / width, -self.bounds.size.height / height); 

It can be seen that this function is used for screen stretching. The stretching ratio is fully stretched horizontally and vertically. This is easy to understand, but the key point is to pay attention to the second parameter:

-self.bounds.size.height / height

The second parameter is a negative value, which means that the drawn area will be stretched in reverse, so the picture will be flipped. After combining CGContextTranslateCTM, the drawing of the picture becomes from the lower left corner of the screen as the starting address of the vertical coordinates, drawing to the upper left corner of the screen.

○ CGColorSpaceCreateDeviceRGB/CGColorSpaceRelease

Used to create and release RGB color space objects. The created object will be CGBitmapContextCreateused .

○ CGBitmapContextCreate/CGContextRelease

The graphics context function used to create and release the bitmap, through which the bitmap data is passed in.

○ CGBitmapContextCreateImage

Create a bitmap.
It should be noted that there is no need to release the bitmap here, because the reference will be used to draw UIView, and then it will enter the life cycle management of UIView.

○ CGContextDrawImage

A layer that renders a bitmap to a UIView.

Guess you like

Origin blog.csdn.net/madaxin/article/details/130337056