Реализация Pinch и Zoom на Android SurfaceView

Я использую SurfaceView для отображения большого изображения (обычно больше, чем экран, но не всегда) в приложении для Android. Это действительно простая графика, и ее легко реализовать с помощью OnTouchListener или GestureDetector. Графика работает в цикле рендеринга, но производительность кажется более чем достаточной для всех реальных устройств (хотя эмулятор может быть немного болезненным).

Я также планирую реализовать Pinch и Zoom на изображении, но я бы предпочел не переходить на OpenGL, поскольку у меня очень мало опыта работы с OpenGL, и использование OpenGL кажется чем-то излишним для чего-то такого простого.

Кажется, что класс android.graphics.Camera может позволить мне реализовать функции масштабирования, которые мне бы хотелось.

Кто-нибудь знает какие-нибудь хорошие примеры, которые показывают реализацию функции, подобной пинч-зуму, в базовом Android SurfaceView?

Кроме того, если вы реализовали что-то подобное, есть мысли о производительности? Стоит ли OpenGL дополнительных хлопот, учитывая, что то, что требуется здесь, так просто?


Вопрос здесь неясен, или я упускаю какую-то ослепительно очевидную документацию / код на сайте разработчиков Android, которые мне следовало найти?

3 ответа

Решение

ОК - наконец-то, успев по-настоящему поработать над этим и поработать над ним некоторое время, я действительно нашел решение, которое решает мою проблему.

Решение опирается на BitmapRegionDecoder (API10+). Это позволяет приложению загружать часть растрового изображения, а не пытаться загрузить все растровое изображение за один раз.

Суть решения:

  1. Уменьшенная версия всего растрового изображения хранится в памяти. Поскольку эта версия сокращена, ее можно хранить там постоянно.
  2. Поток загружается в текущую область просмотра (или чуть больше) растрового изображения в память постоянно (используя BitmapRegionDecoder). Так как он максимально немного больше экрана, он также должен удобно помещаться в памяти.
  3. Поток рендеринга рисует соответствующую версию в Canvas; то есть, если вы уменьшаете масштаб или растровое изображение недоступно (например, потому что оно загружается в фоновом режиме), то используется версия с пониженной дискретизацией.
  4. Панорамирование, Fling и Zoom обрабатываются с помощью GestureListeners.

Благодарность принадлежит Джону Ломбардо за первое воплощение идеи, которую я нашел.

Я открыл свою собственную реализацию вместе с некоторыми другими моими вспомогательными классами по адресу https://github.com/micabyte/android_game

Это довольно недавняя реализация, поэтому в настоящее время ее не приняли боевое крещение от реальных пользователей. Тем не менее, я запустил тесты с отображением растровых изображений размером 8000x4000 пикселей и до сих пор не испытывал проблем. Производительность, безусловно, кажется адекватной моим потребностям.

Реализация пинч и масштабирование - это то, что вы бы сделали с комбинацией ScaleGestureDetector и интерфейса Canvas с матрицей преобразования. Вы захотите использовать одну и ту же матрицу преобразования для обработки как масштаба, так и перевода.

Взгляните на пример One Finger Zoom на сайте разработчиков Sony Ericsson. http://developer.sonymobile.com/wp/tag/zoom/

Другие вопросы по тегам