ios – 如何创建适用于Retina显示的CGBitmapContext,并且不会浪费正常显示的空间?

前端之家收集整理的这篇文章主要介绍了ios – 如何创建适用于Retina显示的CGBitmapContext,并且不会浪费正常显示的空间?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
是否真的,如果在UIKit中,包括drawRect,Retina显示器的HD方面是自动处理的?那么在drawRect中是什么意思,当前的1024 x 768视图的图形上下文实际上是一个2048 x 1536像素的位图上下文?

(更新:如果我使用drawRect中的当前上下文创建一个图像并打印其大小:

CGContextRef context = UIGraphicsGetCurrentContext();
CGImageRef image = CGBitmapContextCreateImage(context);
NSLog(@"width of context %i",(int) CGImageGetWidth(image));
NSLog(@"height of context %i",(int) CGImageGetHeight(image));

然后在新的iPad上,禁用状态栏,打印2048和1536,iPad 2将显示1024和768)

我们实际上享受为我们自动处理的1点= 4像素的豪华.

但是,如果我们使用CGBitmapContextCreate,那么那些将是像素,而不是点? (至少如果我们为该位图提供一个数据缓冲区,缓冲区的大小(字节数)显然不是为了更高的分辨率,而是标准分辨率,即使我们传递NULL作为缓冲区,以便CGBitmapContextCreate处理缓冲区对于我们来说,大小可能与传入数据缓冲区一样,它只是标准分辨率,而不是Retina的分辨率).

我们可以随时为iPad 1和iPad 2以及新iPad创建2048 x 1536,但会浪费内存和处理器以及GPU的功耗,因为它只适用于New iPad.

那么我们必须使用if(){} else {}来创建这样的位图上下文,我们该如何实现呢?并且我们的所有代码CGContextMoveToPoint必须调整Retina显示以使用x * 2和y * 2与非视网膜显示刚刚使用x,y?这对于代码来说可能相当凌乱. (或者我们可以定义一个局部变量scaleFactor并将其设置为[[UIScreen mainScreen] scale],因此标准分辨率为1,如果是视网膜则为2,因此我们的x和y将始终为x * scaleFactor,y * scaleFactor而不是只使用x和y,当我们绘制使用CGContextMoveToPoint等)

看来,如果传递了0.0的比例,UIGraphicsBeginImageContextWithOptions可以自动为Retina创建一个,但是如果我需要创建上下文并保留它(并且使用ivar或UIViewController的属性来保存它),我不认为它可以被使用).如果我不使用UIGraphicsEndImageContext发布它,那么它保留在图形上下文堆栈中,所以看起来像我必须使用CGBitmapContextCreate. (或者我们只是让它留在堆栈的底部,不用担心?)

解决方法

做了更多的研究后,我发现了以下解决方案:

如果您必须使用CGBitmapContextCreate,那么有两个步骤可以使上下文的尺寸和坐标系统适合于标准显示或Retina显示

float scaleFactor = [[UIScreen mainScreen] scale];

CGSize size = CGSizeMake(768,768);

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef context = CGBitmapContextCreate(NULL,size.width * scaleFactor,size.height * scaleFactor,8,size.width * scaleFactor * 4,colorSpace,kCGImageAlphaPremultipliedFirst);

CGContextScaleCTM(context,scaleFactor,scaleFactor);

示例是创建一个768 x 768点区域,而在New iPad上,它将是1536 x 1536像素.在iPad 2上,它是768 x 768像素.

一个关键因素是,CGContextScaleCTM(context,scaleFactor);用于调整坐标系,使Core Graphics的任何绘图(如CGContextMoveToPoint等)自动工作,无论是标准分辨率还是Retina分辨率.

还有一点是UIGraphicsBeginImageContext(CGSizeMake(300,300));将在Retina显示器上创建一个300 x 300像素,而UIGraphicsBeginImageContextWithOptions(CGSizeMake(300,300),NO,0.0);将在Retina显示屏上创建600 x 600像素. 0.0是用于方法调用自动给出标准显示或Retina显示的适当大小.

猜你在找的iOS相关文章