在Android SurfaceView上实现捏合和缩放

10

我在一个Android应用程序中使用SurfaceView显示一张大图(通常比屏幕大,但并不总是)。这是非常简单的图形处理,使用OnTouchListener或GestureDetector实现滚动也很容易。图形运行在Render循环中,但在所有真实设备上性能似乎都足够好(虚拟机可能有些烦人)。

我正在考虑在图像上实现Pinch和Zoom,但我宁愿避免使用OpenGL,因为我对OpenGL的经验非常少,而且使用OpenGL似乎对于这么简单的事情来说有点过度。

似乎android.graphics.Camera类可以让我实现我想要的缩放功能。

是否有人知道任何好的示例展示了如何在基本的Android SurfaceView上实现捏合缩放的功能?

如果您已经实现了这样的功能,关于性能有什么想法吗?鉴于所需的内容如此简单,使用OpenGL是否值得额外的麻烦?


这里的问题是否不清楚,或者我错过了Android开发者网站上我应该找到的某些显而易见的文档或代码?


我也在寻找类似的东西。你找到解决方案了吗?能否请你分享一下呢? - Nir
很不幸,我对此并不满意。当然可以通过“暴力缩放”(使用GestureDetector)来实现,但这不是一个很好的解决方案,可能会占用大量内存。 - Michael A.
嗯...看看这个教程:http://blahti.wordpress.com/2013/01/07/pan-zoom-examples-for-android/ 我还没有自己检查过,但只是快速浏览了一下,它看起来很有前途。 - Michael A.
@JackOfAllTrades,我终于找到了一个令我满意的解决方案。请见下面的答案。 - Michael A.
3个回答

3

好的 - 经过一段时间的研究和工作,我找到了一个解决我问题的解决方案。

该解决方案依赖于BitmapRegionDecoder(API10+)。它允许应用程序加载位图的一部分,而不是尝试一次性加载整个位图。

解决方案的实质:

  1. 内存中保存整个位图的降采样版本。因为此版本已经进行了降采样处理,所以可以永久保存在那里。
  2. 一个线程不断地将当前视口(或略大一些)的位图加载到内存中(使用BitmapRegionDecoder)。由于这最多只比屏幕稍微大一些,所以应该也可以舒适地放在内存中。
  3. 渲染线程将相应版本绘制到画布上;即,如果您正在缩小或者位图不可用(例如,因为它在后台加载),则使用降采样版本。
  4. Pan、Fling 和 Zoom 由GestureListeners 处理。

John Lombardo 是我找到的第一个实现该想法的人,应该向他致谢。

我将我的实现与其他一些实用类一起开源在 https://github.com/micabyte/android_game

这是一个相当新的实现,因此还没有经过真正用户的测试。但是,我已经进行了显示8000x4000像素位图的测试,并且到目前为止没有出现任何问题。对于我的需求来说,性能似乎足够。


0

实现捏合和缩放是通过使用ScaleGestureDetector和Canvas接口与变换矩阵的组合来完成的。您需要利用相同的变换矩阵来处理缩放和平移。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接