如何补偿核心图形的翻转坐标系以便于绘图?

时间:2010-04-22 23:38:30

标签: iphone core-graphics

这真的是一种痛苦,但总是当我在-drawRect中绘制UIImage时,它是颠倒的。

当我翻转坐标时,图像正确绘制,但代价是所有其他CG函数绘制“错误”(翻转)。

当您必须绘制图像和其他内容时,您的策略是什么?是否有任何经验法则如何不能一次又一次地陷入这个问题?

另外,当我翻转y轴时,一件令人讨厌的事情是,来自UIImageView框架的我的CGRect是错误的。而不是原点出现在预期的10,10左上方,它出现在底部。

但与此同时,CGContext的所有正常线条绘制功能都采用正确的坐标。在-drawRect中绘制一条直线10,10左上方的线,将从左上角开始。但同时这很奇怪,因为核心图形实际上有一个翻转的坐标系,底部是y 0。

所以似乎某些东西在那里真的不一致。使用CGContext函数绘制时,坐标为“预期”(cmon,没人认为坐标从左下角开始,这是愚蠢的),而绘制任何类型的图像仍然是“错误”的方式。

您是否使用辅助方法绘制图像?或者有什么有用的东西可以使图像绘制不是屁股上的痛苦吗?

5 个答案:

答案 0 :(得分:29)

问题:原点位于左下角;正y向上(负y向下) 目标:起源于左上角;正y向下(负y向上)。

解决方案:

  1. 根据视图的高度向上移动原点。
  2. 否定(乘以-1)y轴。
  3. 在代码中执行此操作的方法是translate按视图边界的高度和scale按(1,-1)按顺序排列。

    Quartz 2D Programming Guide中有几部分与此主题相关,包括“Drawing to a Graphics Context on iPhone OS”和整个chapter on Transforms。当然,你真的应该阅读整篇文章。

答案 1 :(得分:9)

您可以通过在要转换为UIKit相关坐标的点上应用affinetransform来实现。以下是示例。

// 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);

答案 2 :(得分:4)

此问题的最佳答案是使用UIImage方法drawInRect:绘制图像。我假设您希望图像跨越视图的整个边界。这是您在drawRect:方法中输入的内容。

而不是:

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

写下这个:

UIImage *myImage = [UIImage imageNamed:@"theImage.png"];
CGRect bounds = [self bounds];
[myImage drawInRect:bounds];

答案 3 :(得分:3)

  

这真的是一种痛苦,但总是当我在-drawRect中绘制UIImage时,它是颠倒的。

你是在告诉UIImage绘制,还是获取它的CGImage并绘制它?

“Drawing to a Graphics Context on iPhone OS”所述,UIImages意识到坐标空间的差异,应该正确绘制,而不必自己翻转坐标空间。

答案 4 :(得分:0)

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;
}

使用以下代码调用上述方法: 此代码处理从现有UIImageview获取图像的左半部分并将如此生成的图像设置为新的imageview - imgViewleft

CGContextRef con = UIGraphicsGetCurrentContext();
CGContextDrawImage(con,  
                   CGRectMake(0,0,sz.width/2.0,sz.height),
                   flip(leftReference));
imgViewLeft = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];