【问题标题】:Converting a Quartz method from iOS to OSX将 Quartz 方法从 iOS 转换为 OSX
【发布时间】:2015-02-21 03:00:38
【问题描述】:

我有这个在 iOS 上运行良好的石英类,并在灰色圆圈上绘制橙色披萨切片样式图,我正在尝试将其转换为可可。

+ (UIImage *)circleWithDiameter:(CGFloat) diameter
                          color:(UIColor *)color
                       progress:(CGFloat)progress {


  CGFloat radius = diameter/2.0f;

  CGFloat scale = [[UIScreen mainScreen] scale];  // we need to size the graphics context according to the device scale

  CGRect rect = CGRectMake(0.0f, 0.0f, diameter, diameter);
  UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale);
  CGContextRef context = UIGraphicsGetCurrentContext();


  // create a gray circle background
  CGContextSetLineWidth(context, 0); // set the line width

  CGContextSetFillColorWithColor(context, color.CGColor);

  CGContextBeginPath(context);
  CGContextAddEllipseInRect(context, rect);
  CGContextDrawPath(context, kCGPathFill); // Or kCGPathFill


  // Draw the slice  
  CGFloat angle = progress * 2.0f * M_PI; 

  CGPoint center = CGPointMake(radius, radius);

  CGContextBeginPath(context);
  CGContextMoveToPoint(context, center.x, center.y);

  CGPoint p1 = CGPointMake(center.x + radius * cosf(angle),
                           center.y + radius * sinf(angle));
  CGContextAddLineToPoint(context, p1.x, p1.y);
  CGContextMoveToPoint(context, center.x, center.y);
  CGContextAddArc(context, center.x, center.y, radius, 0.0f, angle, 0);
  CGContextClosePath(context);

  UIColor *orange = [UIColor orangeColor];
  CGContextSetFillColorWithColor(context, orange.CGColor);
  CGContextDrawPath(context, kCGPathFill);

  UIImage *result = UIGraphicsGetImageFromCurrentImageContext();

  CGContextRelease(context);

  return result;

}

这是我转换成可可的类。

+ (NSImage *)circuloWithDiameter:(CGFloat)diameter
                          color:(NSColor *)color
                       progress:(CGFloat)progress {

  CGFloat radius = diameter/2.0f;

  CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];


  // draw the gray circle background
  CGContextSetLineWidth(context, 0); // set the line width

  CGContextSetFillColorWithColor(context, color.CGColor);

  CGContextBeginPath(context);
  CGContextAddEllipseInRect(context, rect);
  CGContextDrawPath(context, kCGPathFill); // Or kCGPathFill


  // draw the orange slice  
  CGFloat angle = progress * 2.0f * M_PI; 

  CGPoint center = CGPointMake(radius, radius);

  CGContextBeginPath(context);
  CGContextMoveToPoint(context, center.x, center.y);

  CGPoint p1 = CGPointMake(center.x + radius * cosf(angle),
                           center.y + radius * sinf(angle));
  CGContextAddLineToPoint(context, p1.x, p1.y);
  CGContextMoveToPoint(context, center.x, center.y);
  CGContextAddArc(context, center.x, center.y, radius, 0.0f, angle, 0);
  CGContextClosePath(context);

  NSColor *orange = [NSColor orangeColor];
  CGContextSetFillColorWithColor(context, orange.CGColor);
  CGContextDrawPath(context, kCGPathFill);


  CGImageRef imageRef = CGBitmapContextCreateImage(context);
  NSImage* result = [[NSImage alloc] initWithCGImage:imageRef size:NSMakeSize(diameter, diameter)];
  CFRelease(imageRef);


  CGContextRelease(context);

  return result;

}

显然转换很顺利,Xcode 没有抱怨任何事情,但是当可可版本运行时,它就在线崩溃了

  CGImageRef imageRef = CGBitmapContextCreateImage(context);

有消息

<Error>: CGBitmapContextCreateImage: invalid context 0x600000160180. This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

怎么了?有什么线索吗?

【问题讨论】:

  • 在 iOS 中,上下文是由 UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale); 创建的,但似乎 OSX 代码在您获取它之前不会创建上下文 [NSGraphicsContext currentContext]
  • 这行CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];不是在创建一个吗?
  • 不,如果存在,它会获取当前上下文。
  • 什么是可可相当于UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale);
  • 看这个link,我对OSX没有任何经验,希望它能工作,+ (NSGraphicsContext *)graphicsContextWithAttributes:(NSDictionary *)attributes

标签: ios macos cocoa cocoa-touch quartz-graphics


【解决方案1】:

AppKit 中的过程略有不同。

首先,您创建一个具有所需大小的NSImage 实例。然后使用-[NSImage lockFocus] 来初始化绘图上下文。这取代了 UIKit 的 UIGraphicsBeginImageContextWithOptions 函数。

至此,你的绘图代码和UIKit一样,使用[[NSGraphicsContext currentContext] graphicsPort]获取当前的CGContextRef

绘制完成后,使用-[NSImage unlockFocus] 处理掉当前的CGContextRef。然后,您可以返回您在函数开始时创建的 NSImage 实例。

【讨论】:

  • 太棒了!有用。唯一的区别是您不需要在最后处理上下文。谢谢!!!!!!!
猜你喜欢
  • 1970-01-01
  • 2015-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
相关资源
最近更新 更多