iOS到Mac GraphicContext解释/转换

我已经在iOS上编程了两年,从来没有在Mac上编程。 我正在处理一些小工具,用于处理iOS开发中的一些简单的图像需求。 无论如何,我有在iOS的工作代码运行完美,但我绝对不知道是什么等同于Mac。

我已经尝试了一堆不同的东西,但我真的不明白如何在“drawRect:”方法之外的Mac上启动graphics上下文。 在iPhone上,我只是使用UIGraphicsBeghinImageContext()。 我知道其他职位已经说过使用lockFocus / unlockFocus,但我不知道如何做到这一点为我的需要工作。 哦,我真的很想念UIImage的“CGImage”属性。 我不明白为什么NSImage不能有一个,虽然听起来有点棘手。

这里是我在iOS上的工作代码 – 基本上它只是从掩码中创build一个reflection的图像,并将它们组合在一起:

UIImage *mask = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"Mask_Image.jpg" ofType:nil]]; UIImage *image = [UIImage imageNamed::@"Test_Image1.jpg"]; UIGraphicsBeginImageContextWithOptions(mask.size, NO, [[UIScreen mainScreen]scale]); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(ctx, 0.0, mask.size.height); CGContextScaleCTM(ctx, 1.f, -1.f); [image drawInRect:CGRectMake(0.f, -mask.size.height, image.size.width, image.size.height)]; UIImage *flippedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); CGImageRef maskRef = mask.CGImage; CGImageRef maskCreate = CGImageMaskCreate(CGImageGetWidth(maskRef), CGImageGetHeight(maskRef), CGImageGetBitsPerComponent(maskRef), CGImageGetBitsPerPixel(maskRef), CGImageGetBytesPerRow(maskRef), CGImageGetDataProvider(maskRef), NULL, false); CGImageRef masked = CGImageCreateWithMask([flippedImage CGImage], maskCreate); CGImageRelease(maskCreate); UIImage *maskedImage = [UIImage imageWithCGImage:masked]; CGImageRelease(masked); UIGraphicsBeginImageContextWithOptions(CGSizeMake(image.size.width, image.size.height + (image.size.height * .5)), NO, [[UIScreen mainScreen]scale]); [image drawInRect:CGRectMake(0,0, image.size.width, image.size.height)]; [maskedImage drawInRect:CGRectMake(0, image.size.height, maskedImage.size.width, maskedImage.size.height)]; UIImage *anotherImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); //do something with anotherImage 

任何build议(简单地)在Mac上实现这一点?

下面是一个简单的例子,在NSImage中绘制一个蓝色圆圈(我在这个例子中使用了ARC,添加了保留/释放的味道)

 NSSize size = NSMakeSize(50, 50); NSImage* im = [[NSImage alloc] initWithSize:size]; NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:size.width pixelsHigh:size.height bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace bytesPerRow:0 bitsPerPixel:0]; [im addRepresentation:rep]; [im lockFocus]; CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort]; CGContextClearRect(ctx, NSMakeRect(0, 0, size.width, size.height)); CGContextSetFillColorWithColor(ctx, [[NSColor blueColor] CGColor]); CGContextFillEllipseInRect(ctx, NSMakeRect(0, 0, size.width, size.height)); [im unlockFocus]; [[im TIFFRepresentation] writeToFile:@"/Users/USERNAME/Desktop/foo.tiff" atomically:NO]; 

主要的区别是,在OS X上,您首先必须创build图像,然后才能开始绘制; 在iOS上创build上下文,然后从中提取图像。

基本上,lockFocus使当前的上下文成为图像,你直接在它上面绘制,然后使用图像。

我不完全确定这是否回答了您的所有问题,但我认为这至less是其中的一部分。

那么,这里是关于UIGraphicsBeginImageContextWithOptions的说明:

UIGraphicsBeginImageContextWithOptions

用指定的选项创build一个基于位图的graphics上下文。

iOS中可用的OS X等价物(和UIGraphicsBeginImageContextWithOptions可能是一个包装物)是CGBitmapContextCreate

声明为:

 CGContextRef CGBitmapContextCreate ( void *data, size_t width, size_t height, size_t bitsPerComponent, size_t bytesPerRow, CGColorSpaceRef colorspace, CGBitmapInfo bitmapInfo ); 

尽pipe它是一个C API,但您可以将CGBitmapContext视为CGContext的一个子类。 它呈现给像素缓冲区,而CGContext呈现给抽象目的地。

对于UIGraphicsGetImageFromCurrentImageContext ,可以使用CGBitmapContextCreateImage并传递位图上下文来创build一个CGImage。

Cobbal的答案是Swift(2.1 / 10.11 API兼容)版本

  let size = NSMakeSize(50, 50); let im = NSImage.init(size: size) let rep = NSBitmapImageRep.init(bitmapDataPlanes: nil, pixelsWide: Int(size.width), pixelsHigh: Int(size.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSCalibratedRGBColorSpace, bytesPerRow: 0, bitsPerPixel: 0) im.addRepresentation(rep!) im.lockFocus() let rect = NSMakeRect(0, 0, size.width, size.height) let ctx = NSGraphicsContext.currentContext()?.CGContext CGContextClearRect(ctx, rect) CGContextSetFillColorWithColor(ctx, NSColor.blackColor().CGColor) CGContextFillRect(ctx, rect) im.unlockFocus() 

Swbal3的Cobbal的答案

  let size = NSMakeSize(50, 50); let im = NSImage.init(size: size) let rep = NSBitmapImageRep.init(bitmapDataPlanes: nil, pixelsWide: Int(size.width), pixelsHigh: Int(size.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSCalibratedRGBColorSpace, bytesPerRow: 0, bitsPerPixel: 0) im.addRepresentation(rep!) im.lockFocus() let rect = NSMakeRect(0, 0, size.width, size.height) let ctx = NSGraphicsContext.current()?.cgContext ctx!.clear(rect) ctx!.setFillColor(NSColor.black.cgColor) ctx!.fill(rect) im.unlockFocus()