使用普通的 CALayer 显示图像或 UIImage

Posted

技术标签:

【中文标题】使用普通的 CALayer 显示图像或 UIImage【英文标题】:Display an image or UIImage with a plain CALayer 【发布时间】:2009-10-14 08:12:38 【问题描述】:

我经常读到使用CALayer 而不是UIImageView 会在大量使用图像时提高性能。这是有道理的,因为UIImageView 会在内存中生成 3 个图像副本,这是核心动画所需要的。但就我而言,我不使用核心动画。

如何将UIImage(或其图像数据)分配给CALayer,然后显示?

【问题讨论】:

你在哪里读到这个? UIView 通常是围绕 CALayers 的轻量级包装器,我没有看到它们在内存或显示性能方面有太大差异。我也不确定我是否在内存参数中购买了 3 个图像副本。无论如何,CALayers 确实是 Core Animation 的一部分(因此是 CA 前缀)。 【参考方案1】:
UIImage*    backgroundImage = [UIImage imageNamed:kBackName];
CALayer*    aLayer = [CALayer layer];
CGFloat nativeWidth = CGImageGetWidth(backgroundImage.CGImage);
CGFloat nativeHeight = CGImageGetHeight(backgroundImage.CGImage);
CGRect      startFrame = CGRectMake(0.0, 0.0, nativeWidth, nativeHeight);
aLayer.contents = (id)backgroundImage.CGImage;
aLayer.frame = startFrame;

或在 Swift Playground 中(您必须在 Playground 的资源文件中提供自己的 PNG 图像。我使用的是“FrogAvatar”的示例。)

  //: Playground - noun: a place where people can play
import UIKit

if let backgroundImage = UIImage(named: "FrogAvatar") // you will have to provide your own image in your playground's Resource file

    let height = backgroundImage.size.height
    let width = backgroundImage.size.width

    let aLayer = CALayer()
    let startFrame = CGRect(x: 0, y: 0, width: width, height: height)

    let aView = UIView(frame: startFrame)
    aLayer.frame = startFrame
    aLayer.contentsScale = aView.contentScaleFactor
    aLayer.contents = backgroundImage.cgImage
    aView.layer.addSublayer(aLayer)
    aView // look at this via the Playground's ? eye icon

【讨论】:

谢谢!为什么你写 (id)backgroundImage 而不仅仅是 backgroundImage?编译器不应该认识到你在那里有一个 UIImage 吗?或者 CGImage 属性是否无法识别?也许缺少导入? 我试过了。但是最有趣的一点是缺失:如何在屏幕上显示它?我想尽可能避免使用 UIViews。 您需要将 CALayer 添加为某些 UIView 层的子层。每个图层不需要自己的视图,但图层层次结构确实需要驻留在某个视图中,以便可以将其绘制到屏幕上。 需要强制转换为 id,因为 CGImageRef 没有在标题中定义为从 id 降序,但这就是定义 CALayer 的 contents 属性的方式。 只是想提一下,您应该将原生图像大小除以[[UIScreen mainScreen] scale]【参考方案2】:

ARC 版本需要不同的演员表:

self.myView.layer.contents = (__bridge id) self.myImage.CGImage;

【讨论】:

【参考方案3】:
CALayer *layer = [[CALayer alloc] init];
layer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"REWIFISocketOff"].CGImage);

【讨论】:

如果您要包含解释而不仅仅是代码,此答案将得到显着改善

以上是关于使用普通的 CALayer 显示图像或 UIImage的主要内容,如果未能解决你的问题,请参考以下文章

无法让 CALayer 在 UIView 中显示

图像更改 CALayer 核心动画

如果 CALayer 边界如何独立地 CALayer 图像缩放

如何在 UITableViewCell 中添加一张或多张图片?

在 iOS 7 的模态视图或表单中显示 UIImagePickerController?

使用普通/高亮图像创建自定义 UIButton