了解画布和曲面概念


114

我正在努力理解绘制过程,SurfaceView因此整个过程Surface/ Canvas/Bitmap系统,该系统采用的是Android使用。

我已经阅读了所有文章和API文档页面,这些页面可以在android-developers网站上找到,一些关于android图形的教程,LunarLander源代码以及这个问题

请告诉我,这些陈述中哪些是正确的,哪些不是,以及原因。

  1. Canvas有它自己的Bitmap附件。Surface有它自己的Canvas附件。
  2. 所有View窗口共享相同的窗口Surface,因此共享相同的窗口Canvas
  3. SurfaceView是的子类View,与其他View子类及其View本身不同,它有自己Surface的特点。

另外还有一个问题:

  • Surface如果已经有Canvas使用位图进行高级操作的原因,为什么需要一个类。举一个Canvas不适合做Surface可以做的工作的情况的例子。

Answers:


223

以下是一些定义:

  • Surface是一个对象,其中包含要合成到屏幕的像素。您在屏幕上看到的每个窗口(对话框,全屏活动,状态栏)都有其自己的曲面,Surface Flinger会以其正确的Z顺序将其渲染到最终显示中。一个表面通常具有一个以上的缓冲区(通常是两个)来进行双缓冲渲染:当表面镶边器使用最后一个缓冲区合成屏幕时,应用程序可以绘制其下一个UI状态,而无需等待应用程序完成画画。

  • 窗口基本上就像您在桌面上想到的窗口一样。它具有单个Surface,其中呈现了窗口的内容。应用程序与“窗口管理器”交互以创建窗口。窗口管理器为每个窗口创建一个Surface并将其提供给应用程序进行绘制。应用程序可以在Surface中绘制任何内容。窗口管理器只是一个不透明的矩形。

  • 视图是窗口内部的交互式UI元素。窗口具有附加的单个视图层次结构,该视图层次结构提供了窗口的所有行为。每当需要重绘窗口时(例如,由于视图自身无效),都会在窗口的Surface中完成此操作。曲面被锁定,这将返回可用于绘制到其中的Canvas。绘制遍历在层次结构中进行,将Canvas递给每个视图以绘制其UI部分。完成后,将对Surface进行解锁和发布,以便将刚绘制的缓冲区交换到前景,然后由Surface Flinger将其合成到屏幕。

  • SurfaceView是View的一种特殊实现,它还创建了自己的专用Surface,供应用程序直接绘制到其中(在普通视图层次结构之外,否则,该视图层次结构必须共享窗口的单个Surface)。它的工作方式比您预期的要简单-所有SurfaceView所做的只是要求窗口管理器创建一个新窗口,告诉该窗口以Z顺序将该窗口放置在SurfaceView窗口的正后方或正前方,并将其定位为匹配SurfaceView出现在包含窗口中的位置。如果将曲面放置在主窗口后面(按Z顺序),SurfaceView也会用透明填充其在主窗口中的一部分,以便可以看到该曲面。

  • 位图只是一些像素数据的接口。直接创建像素时,像素可能是由位图本身分配的,也可能指向的是它不拥有的像素,例如在内部将Canvas挂接到Surface进行绘制时发生的内部情况。(将创建一个位图,并指向Surface的当前图形缓冲区。)

同样,请记住,正如这暗示的那样,SurfaceView是一个非常重的对象。如果在特定的UI中有多个SurfaceView,请停下来考虑是否真的需要这样做。如果您有两个以上,则几乎可以肯定有太多。


非常感谢你!答案使事情变得更清楚。但是,关于将Canvas挂接到Surface的部分内容尚不清楚。无法想象在哪里需要这种操作。接下来可以作为该操作的示例:使用LockCanvas()方法从SurfaceHolder获取的Canvas上绘制位图吗?
fyodorananiev 2011年

1
这就是绘图发生的方式。Canvas是2D绘图API。如果要在表面上绘制o,则需要制作一个Canvas指向其缓冲区以使用Canvas 2d绘图API对其进行绘制。
hackbod 2011年

6
除了#hackbod's答案,SurfaceView还可以从View对象无法实现的辅助线程进行渲染
Mohanraj Balasubramaniam 2015年

47

窗口,曲面,画布和位图的概念概述

这是关于窗口,曲面,画布和位图之间如何进行交互的非常基本且简单的概念概述。
有时,视觉表示有助于理解扭曲的概念。
我希望该图形可以对某人有所帮助。


4
Visualy 图片都优于文字:d
行家ツ

18

位图只是一个像素集合的包装器。将其视为具有其他一些便捷功能的像素阵列。

画布只是包含所有绘制方法的类。如果您熟悉它,它类似于AWT / Swing中的Graphics类。有关如何绘制圆或框等的所有逻辑,均包含在Canvas中。画布可以在位图或开放的GL容器上绘制,但是没有理由将来可以将其扩展以绘制到其他类型的栅格上。

SurfaceView是一个包含Surface的视图。表面类似于位图(它具有像素存储)。我不知道它是如何实现的,但我想它是一种位图包装器,它具有与屏幕显示直接相关的其他方法(这是表面的原因,位图过于通用)。您可以从Surface获取Canvas,这实际上是与基础位图关联的Canvas。

你的问题。

1.Canvas有自己的位图。Surface具有自己的画布。

是的,画布可以在位图(或打开的GL面板)上运行。Surface为您提供了可以在其位图样式像素存储所使用的任何Surface上运行的Canvas。

2.窗口的所有视图共享相同的表面,因此共享相同的画布。

不。您可以根据需要拥有任意数量的表面视图。

3.SurfaceView是View的子类,与其他View的子类和View本身不同,SurfaceView具有自己的Surface可以插入。

是。就像ListView是View的子类一样,它具有自己的List数据结构。View的每个子类都有不同的功能。


1
所以,BitmapSurface只是不同的像素商店的种类和Canvas可以包裹他们的?
fyodorananiev 2011年

2
基本上是。除Canvas无法写入表面外,它可以在Surface用作其自己的像素存储的任何对象上进行操作(无需查看android源代码,我无法确定它是什么)。这可能是某种Bitmap扩展,因为Canvas仅提供Bitmap和GL的构造函数。
sksamuel

很大的帮助,谢谢!关于答案2.在我的问题中,我指的是标准视图,而不是SurfaceViews。假设我有很多字段和按钮的RelativeLayout。在这种情况下,Surface是否附加到整个窗口并由视图层次结构中的所有视图共享?
fyodorananiev 2011年

1
记住Surface只是像素的集合。因此,每个表面视图都有自己的表面,并且每个表面视图都可以呈现在屏幕的不同部分。它们不必填满整个屏幕(尽管这是通常的用法,以便在全屏游戏上渲染图形)。
sksamuel

1
我真的不会认为Bitmap和Surface是等效的。曲面是曲面合成器(窗口合成器)知道的对象。也就是说,它是直接在屏幕上看到的东西,已经在屏幕上的Z顺序等
hackbod
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.