How to compensate the flipped coordinate system of core graphics for easy drawing?

前端 未结 5 1490
灰色年华
灰色年华 2020-12-08 07:18

It\'s really a pain, but always when I draw an UIImage in -drawRect:, it\'s upside-down.

When I flip the coordinates, the image draws correctly, but at the cost of a

相关标签:
5条回答
  • 2020-12-08 07:31

    It's really a pain, but always when I draw an UIImage in -drawRect:, it's upside-down.

    Are you telling the UIImage to draw, or getting its CGImage and drawing that?

    As noted in “Drawing to a Graphics Context on iPhone OS”, UIImages are aware of the difference in co-ordinate spaces and should draw themselves correctly without you having to flip your co-ordinate space yourself.

    0 讨论(0)
  • 2020-12-08 07:40

    You can do that by apply affinetransform on the point you want to convert in UIKit related coordinates. Following is example.

    // Create a affine transform object
    CGAffineTransform transform = CGAffineTransformMakeScale(1, -1);
    // First translate your image View according to transform
    transform = CGAffineTransformTranslate(transform, 0, - imageView.bounds.size.height);
    // Then whenever you want any point according to UIKit related coordinates apply this transformation on the point or rect.
    // To get tranformed point
    CGPoint newPointForUIKit = CGPointApplyAffineTransform(oldPointInCGKit, transform);
    // To get transformed rect
    CGRect newRectForUIKit = CGRectApplyAffineTransform(oldPointInCGKit, transform);
    
    0 讨论(0)
  • 2020-12-08 07:55

    Problem: Origin is at lower-left corner; positive y goes upward (negative y goes downward).
    Goal: Origin at upper-left corner; positive y going downward (negative y going upward).

    Solution:

    1. Move origin up by the view's height.
    2. Negate (multiply by -1) the y axis.

    The way to do this in code is to translate up by the view bounds' height and scale by (1, -1), in that order.

    There are a couple of portions of the Quartz 2D Programming Guide that are relevant to this topic, including “Drawing to a Graphics Context on iPhone OS” and the whole chapter on Transforms. Of course, you really should read the whole thing.

    0 讨论(0)
  • 2020-12-08 07:55
    CGImageRef flip (CGImageRef im) {
        CGSize sz = CGSizeMake(CGImageGetWidth(im), CGImageGetHeight(im));
        UIGraphicsBeginImageContextWithOptions(sz, NO, 0);
        CGContextDrawImage(UIGraphicsGetCurrentContext(),
                           CGRectMake(0, 0, sz.width, sz.height), im);
        CGImageRef result = [UIGraphicsGetImageFromCurrentImageContext() CGImage];
        UIGraphicsEndImageContext();
        return result;
    }
    

    Call the above method using the code below: This code deals with getting the left half of an image from an existing UIImageview and setting the thus generated image to a new imageview - imgViewleft

    CGContextRef con = UIGraphicsGetCurrentContext();
    CGContextDrawImage(con,  
                       CGRectMake(0,0,sz.width/2.0,sz.height),
                       flip(leftReference));
    imgViewLeft = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
    
    0 讨论(0)
  • 2020-12-08 07:57

    The better answer to this problem is to use the UIImage method drawInRect: to draw your image. I'm assuming you want the image to span the entire bounds of your view. This is what you'd type in your drawRect: method.

    Instead of:

    CGContextRef ctx = UIGraphicsGetCurrentContext();  
    UIImage *myImage = [UIImage imageNamed:@"theImage.png"];  
    CGImageRef img = [myImage CGImage];
    CGRect bounds = [self bounds];
    CGContextDrawImage(ctx, bounds, img);
    

    Write this:

    UIImage *myImage = [UIImage imageNamed:@"theImage.png"];
    CGRect bounds = [self bounds];
    [myImage drawInRect:bounds];
    
    0 讨论(0)
提交回复
热议问题