如何从 UIView 创建 CGLayer 进行离屏绘图

发布于 2024-10-16 21:53:13 字数 1159 浏览 1 评论 0原文

我已经阅读了我认为是 Quartz 2D 编程指南的相关部分,但找不到以下问题的答案(他们似乎在文档中没有过多谈论 iOS):

我的应用程序在 a 中显示绘图UIView。我时不时地必须以某种方式更新绘图,例如更改其中一个形状的填充颜色(我将 CGPathRefs 保留为重要的形状,以便能够使用不同的填充颜色重新绘制它们之后)。正如上述文档第 169 页的“使用 CGLayer 绘图”一节中所述,我正在考虑将整个绘图绘制到从 CGLayer 获取的 CGContext 中。 >,就像这样:

CGContextRef offscreenContext = CGLayerGetContext(offscreenLayer);

然后我可以在 CGContext 中进行离屏更新,并将 CGLayer 绘制到 UIView 中的 UIView 中 我遇到的

CGContextDrawLayerAtPoint(viewContext, CGPointZero, offscreenLayer);

问题是,我从哪里获取我的CGLayer?我的理解是我必须使用 CGLayerCreateWithContext 来实现它,并提供 CGContext 作为参数,它从中继承大部分属性。显然,正确的上下文应该是我正在使用的 UIView 的上下文,

CGContextRef viewContext = UIGraphicsGetCurrentContext();

但如果我没有记错的话,我只能在 drawRect: 方法中获得它,并且假设下次调用该方法时给定的上下文将与该上下文相同是无效的,即我只能在该方法中本地使用该 CGContext。

那么,我怎样才能获得一个CGContext,我可以用它来初始化我的CGLayer来创建一个屏幕外的CGContext来绘制,然后绘制整个层回到我的 UIViewCGContext 中?

PS:当你在做的时候;如果以上任何内容没有意义或不理智,请告诉我。我刚刚开始了解 Quartz 2D。

I have read what I believe to be the relevant parts of the Quartz 2D Programming Guide, but cannot find an answer to the following (they don't seem to talk a lot about iOS in the document):

My application displays a drawing in a UIView. Every now and then I have to update the drawing in some way, e.g. change the fill colour of one of the shapes (I keep CGPathRefs to the important shapes to be able to redraw them with a different fill colour later). As described in the Section "Drawing With a CGLayer" on page 169 of the aforementioned document, I was thinking of drawing the entire drawing into a CGContext that I would obtain from a CGLayer, like so:

CGContextRef offscreenContext = CGLayerGetContext(offscreenLayer);

Then I could do my updating off-screen into the CGContext and draw the CGLayer into my UIView in the UIView's drawRect: method, like so:

CGContextDrawLayerAtPoint(viewContext, CGPointZero, offscreenLayer);

The problem I am having is, where do I get my CGLayer from? My understanding is I have to make it using CGLayerCreateWithContext and supply a CGContext as a parameter from which it inherits most of it's properties. Obviously, the right context would be the context of the UIView, that I am getting with

CGContextRef viewContext = UIGraphicsGetCurrentContext();

but if I am not mistaken, I can only get that within the drawRect: method and it is not valid to assume that the context I am given there will be the same one next time the method is called, i.e. I can only use that CGContext locally within the method.

So, how can I get a CGContext that I can use to initialise my CGLayer to create an offscreen CGContext to draw into and then draw the entire layer back into my UIView's CGContext?

PS: While you're at it; if anything above does not make sense or is not sane, please let me know. I am just starting to get my head around Quartz 2D.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪我鬧 2024-10-23 21:53:13

首先,如果您是在 iOS 环境中执行此操作,我认为您是对的。文档明确指出,获取 CGContextRef 的唯一方法是

CGContextRef ctx = UIGraphicGetCurrentContext();

然后您使用该上下文来创建 CGLayer

CGLayerRef layer = CGLayerCreateWithContext(ctx, (CGSize){0,0}, NULL);

如果您想在该图层上绘图,您可以使用从图层中获得的上下文来绘制它。 (它与您之前创建 CGLayer 时传入的上下文有些不同)。我猜测 CGLayerCreateWithContext 保存了它可以从传入的上下文中获取的信息,但不是所有信息。 (其中一个示例是 ColorSpace 信息,当您使用 CGLayer 中的上下文填充某些内容时,您必须重新指定)。

您可以从 CGLayerGetContext() 函数获取 CGLayer 上下文引用并使用它来绘制。

CGContextRef layerCtx = CGLayerGetContext(layer);
CGContextBeginPath(layerCtx);
CGContextMoveToPoint(layerCtx, -10, 10);
CGContextAddLineToPoint(layerCtx, 100, 10);
CGContextAddLineToPoint(layerCtx, 100, 100);
CGContextClosePath(layerCtx);

我发现的一点是,当您在屏幕外绘制某些内容时,它会自动将其剪辑到屏幕外。 (有道理,所以它不会绘制看不见的东西)但是当您移动图层时(使用矩阵变换)。剪切路径未显示(丢失)。

最后一件事,如果将对图层的引用保存到变量中,然后想要绘制它,则可以使用 CGContextDrawLayerAtPoint() 方法,例如

CGContextDrawLayerAtPoint(ctx, (CGPoint) {newPointX, newPointY}, layer);

它会类似于“stampt”或“draw” newPointX 和新 PointY 坐标处的图层。

我希望能回答您的问题,如果没有请告诉我。

First of all, if you are doing it from in an iOS environment, I think you are right. The documentation clearly said that the only way to obtain a CGContextRef is by

CGContextRef ctx = UIGraphicGetCurrentContext();

Then you use that context for creating the CGLayer with

CGLayerRef layer = CGLayerCreateWithContext(ctx, (CGSize){0,0}, NULL);

And if you want to draw on that layer, you have to draw it with the context you get from the layer. (It is somewhat different from the context you passed in earlier to create the CGLayer). Im guessing the CGLayerCreateWithContext saves the information it can get from the context passed in, but not everything. (One of the example is the ColorSpace information, you have to re-specify when you fill something with the context from CGLayer).

You can get the CGLayer context reference from the CGLayerGetContext() function and use that to draw.

CGContextRef layerCtx = CGLayerGetContext(layer);
CGContextBeginPath(layerCtx);
CGContextMoveToPoint(layerCtx, -10, 10);
CGContextAddLineToPoint(layerCtx, 100, 10);
CGContextAddLineToPoint(layerCtx, 100, 100);
CGContextClosePath(layerCtx);

One point that I found out is when you draw something offscreen, it automatically clips the thing offscreen. (make sense, so it doesnt draw things that is not seen) but when you move the layer (using the matrix transformation). The clipped path is not showing (missing).

One last thing, if you save the reference to a layer into a variable and later on you want to draw it, you can use CGContextDrawLayerAtPoint() method like

CGContextDrawLayerAtPoint(ctx, (CGPoint) {newPointX, newPointY}, layer);

It will sort of "stampt" or "draw" the layer at that newPointX and new PointY coordinate.

I hope that answer your question, if its not please let me know.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文