简体   繁体   English

在Android SurfaceView上实现捏合和缩放

[英]Implementing Pinch and Zoom on Android SurfaceView

I am using a SurfaceView to display a large image (usually bigger than the screen, but not always) in an Android App. 我使用SurfaceView在Android应用程序中显示大图像(通常比屏幕大,但并不总是如此)。 This is really trivially simple graphics, and it is easy to implement scrolling using an OnTouchListener or GestureDetector. 这实际上是简单的图形,使用OnTouchListener或GestureDetector很容易实现滚动。 Graphics run in a Render loop, but performance seems to be more than adequate for all real devices (the emulator can be a bit of a pain, though). 图形在Render循环中运行,但是对于所有真实设备来说,性能似乎已经足够了(尽管仿真器可能有点痛苦)。

I'm considering implementing Pinch and Zoom on the image as well, but I would prefer to avoid having to go to OpenGL, since I have very little experience with OpenGL and using OpenGL seems like pretty much overkill for something this simple. 我正在考虑在图像上实现Pinch和Zoom,但我更愿意避免使用OpenGL,因为我对OpenGL的经验很少,并且使用OpenGL对于这么简单的事情来说似乎有些过分。

It seems as if the android.graphics.Camera class might allow me to implement the zoom functionality that I would like. 似乎android.graphics.Camera类可能允许我实现我想要的缩放功能。

Does anyone know of any good examples that show the implementation of a pinch-zoom like functionality on a basic Android SurfaceView? 有没有人知道在基本的Android SurfaceView上实现类似缩放功能的任何好例子?

Also if you have implemented something like this, any thoughts on performance? 此外,如果你已经实现了这样的事情,任何关于性能的想法? Is OpenGL worth the extra hassle, given that what is required here is so simple? OpenGL是否值得额外麻烦,因为这里需要的是如此简单?


Is the question unclear here, or am I missing some blindingly obvious documentation/code on the Android developer site that I should have found? 这个问题不清楚,或者我在Android开发者网站上遗漏了一些我应该找到的令人眼花缭乱的明显文档/代码?

OK - having finally had time to really work and research on this for some length of time, I actually found a solution that solves the problem I had. 好的 - 我终于有时间真正地工作并研究了一段时间,我实际上找到了解决问题的解决方案。

The solution relies on the BitmapRegionDecoder (API10+). 该解决方案依赖于BitmapRegionDecoder(API10 +)。 What this does is allow the app to load in a part of a bitmap, rather than attempting to load the entire bitmap in one go. 这样做是允许应用程序加载位图的一部分,而不是试图一次加载整个位图。

The essence of the solution: 解决方案的本质:

  1. A downsampled version of the entire bitmap is kept in memory. 整个位图的下采样版本保存在内存中。 Because this version is downsampled, it can be kept there permanently. 由于此版本已被下采样,因此可以永久保存。
  2. A thread loads in the current viewport (or a bit more) of the bitmap to memory continually (using BitmapRegionDecoder). 线程将位图的当前视口(或更多)连续加载到内存中(使用BitmapRegionDecoder)。 As this is at most slightly larger than the screen, this should also fit comfortably in memory. 因为它最多比屏幕略大,所以它也应该舒适地适合记忆。
  3. The rendering thread draws the appropriate version to the Canvas; 渲染线程将适当的版本绘制到Canvas; ie, if you are zooming out or the bitmap is not available (eg, because it is loading in the background), then the downsampled version is used. 即,如果您缩小或位图不可用(例如,因为它在后台加载),则使用缩减采样版本。
  4. Pan, Fling, and Zoom are handled with GestureListeners. Pan,Fling和Zoom由GestureListeners处理。

Credit goes to John Lombardo for the first implementation of the idea I've found. 感谢John Lombardo首次实现我发现的想法。

I open-sourced my own implementation along with some of my other utility classes at https://github.com/micabyte/android_game 我在https://github.com/micabyte/android_game上开源我自己的实现以及我的一些其他实用程序类

It's a pretty recent implementation, so its not had the baptism of fire from real users at this time. 这是一个非常新的实现,因此它目前没有受到真实用户的火灾洗礼。 However, I've run tests with displaying 8000x4000 pixel bitmaps and had no issues so far. 但是,我已经运行测试显示8000x4000像素位图,到目前为止没有问题。 Performance certainly seems adequate for my needs. 性能当然似乎足以满足我的需求。

Implementing pinch and zoom is something that you would do with a combination of the ScaleGestureDetector and the Canvas interface with a transformation matrix. 使用ScaleGestureDetector和Canvas接口与转换矩阵的组合,可以实现捏合和缩放。 You'll want to make use of the same transformation matrix to handle both scale and translation. 您将希望使用相同的转换矩阵来处理缩放和转换。

Take a look at the One Finger Zoom example on the Sony Ericsson developer site. 请查看索尼爱立信开发者网站上的One Finger Zoom示例。 http://developer.sonymobile.com/wp/tag/zoom/ http://developer.sonymobile.com/wp/tag/zoom/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM