gpt4 book ai didi

ios - 如何创建适用于 Retina 显示的 CGBitmapContext 而不会浪费常规显示空间?

转载 作者:技术小花猫 更新时间:2023-10-29 10:12:33 26 4
gpt4 key购买 nike

如果在 UIKit 中,包括 drawRect,是否会自动处理 Retina 显示的高清方面?那么这是否意味着在 drawRect 中,1024 x 768 View 的当前图形上下文实际上是一个 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 以及 New iPad 创建 2048 x 1536,但这会浪费内存、处理器和 GPU 能力,因为只有 New iPad 才需要它。

那么我们是否必须使用 if () { } else { } 来创建这样的位图上下文,我们实际上是如何做到的?我们所有的代码 CGContextMoveToPoint 都必须针对 Retina 显示进行调整以使用 x * 2y * 2 与仅使用非视网膜显示x, y 还有吗?这对于代码来说可能非常困惑。 (或者我们可以定义一个局部变量 scaleFactor 并将其设置为 [[UIScreen mainScreen] scale] 所以标准分辨率为 1,视网膜分辨率为 2,所以我们的 xy 将永远是 x * scaleFactor, y * scaleFactor 而不仅仅是 xy 当我们使用 CGContextMoveToPoint 等绘制时)

似乎 UIGraphicsBeginImageContextWithOptions 如果传入 0.0 的比例,则可以自动为 Retina 创建一个,但我认为如果我需要创建上下文并保留它,则不能使用它(并使用 UIViewController 的 ivar 或属性来保存它)。如果我不使用 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 区域,而在新 iPad 上,它将是 1536 x 1536 像素。在 iPad 2 上,它是 768 x 768 像素

一个关键因素是,CGContextScaleCTM(context, scaleFactor, 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 - 如何创建适用于 Retina 显示的 CGBitmapContext 而不会浪费常规显示空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10867767/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com