10

I am using a SurfaceView to display a large image (usually bigger than the screen, but not always) in an Android App. This is really trivially simple graphics, and it is easy to implement scrolling using an OnTouchListener or 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).

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.

It seems as if the android.graphics.Camera class might allow me to implement the zoom functionality that I would like.

Does anyone know of any good examples that show the implementation of a pinch-zoom like functionality on a basic 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?


Is the question unclear here, or am I missing some blindingly obvious documentation/code on the Android developer site that I should have found?

Michael A.
  • 4,163
  • 3
  • 28
  • 47
  • I am also looking for something like this. Did you get the solution. Can you please share it. – Nir Dec 19 '12 at 07:22
  • Unfortunately, nothing that I am really happy with. It is of course possible to "brute-force" zoom (using GestureDetector), but it's not a very good solution and can be awfully memory intensive. – Michael A. Jan 06 '13 at 12:24
  • Hmm... take a look at this tutorial: http://blahti.wordpress.com/2013/01/07/pan-zoom-examples-for-android/ I haven't checked it out myself yet, but just based on a quick glance, it does look promising. – Michael A. Jan 07 '13 at 13:05
  • @JackOfAllTrades I finally found a solution to this that I am happy with. See answer below. – Michael A. Feb 28 '13 at 00:26

3 Answers3

3

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+). 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). 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; i.e., if you are zooming out or the bitmap is not available (e.g., because it is loading in the background), then the downsampled version is used.
  4. Pan, Fling, and Zoom are handled with GestureListeners.

Credit goes to John Lombardo for the first implementation of the idea I've found.

I open-sourced my own implementation along with some of my other utility classes at 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. Performance certainly seems adequate for my needs.

Michael A.
  • 4,163
  • 3
  • 28
  • 47
0

Implementing pinch and zoom is something that you would do with a combination of the ScaleGestureDetector and the Canvas interface with a transformation matrix. You'll want to make use of the same transformation matrix to handle both scale and translation.

dagalpin
  • 1,297
  • 8
  • 8
0

Take a look at the One Finger Zoom example on the Sony Ericsson developer site. http://developer.sonymobile.com/wp/tag/zoom/

Akos Cz
  • 12,711
  • 1
  • 37
  • 32