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

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

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

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

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

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


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

Ответ 1

OK - наконец, успев поработать и исследовать это в течение некоторого времени, я нашел решение, которое решает проблему, которую я имел.

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

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

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

Кредит отправляется Джону Ломбардо для первой реализации идеи, которую я нашел.

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

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

Ответ 2

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