Реализация Pinch и Zoom на Android SurfaceView
Я использую SurfaceView для отображения большого изображения (обычно больше, чем экран, но не всегда) в приложении для Android. Это действительно простая графика, и ее легко реализовать с помощью OnTouchListener или GestureDetector. Графика работает в цикле рендеринга, но производительность кажется более чем достаточной для всех реальных устройств (хотя эмулятор может быть немного болезненным).
Я также планирую реализовать Pinch и Zoom на изображении, но я бы предпочел не переходить на OpenGL, поскольку у меня очень мало опыта работы с OpenGL, и использование OpenGL кажется чем-то излишним для чего-то такого простого.
Кажется, что класс android.graphics.Camera может позволить мне реализовать функции масштабирования, которые мне бы хотелось.
Кто-нибудь знает какие-нибудь хорошие примеры, которые показывают реализацию функции, подобной пинч-зуму, в базовом Android SurfaceView?
Кроме того, если вы реализовали что-то подобное, есть мысли о производительности? Стоит ли OpenGL дополнительных хлопот, учитывая, что то, что требуется здесь, так просто?
Вопрос здесь неясен, или я упускаю какую-то ослепительно очевидную документацию / код на сайте разработчиков Android, которые мне следовало найти?
3 ответа
ОК - наконец-то, успев по-настоящему поработать над этим и поработать над ним некоторое время, я действительно нашел решение, которое решает мою проблему.
Решение опирается на BitmapRegionDecoder (API10+). Это позволяет приложению загружать часть растрового изображения, а не пытаться загрузить все растровое изображение за один раз.
Суть решения:
- Уменьшенная версия всего растрового изображения хранится в памяти. Поскольку эта версия сокращена, ее можно хранить там постоянно.
- Поток загружается в текущую область просмотра (или чуть больше) растрового изображения в память постоянно (используя BitmapRegionDecoder). Так как он максимально немного больше экрана, он также должен удобно помещаться в памяти.
- Поток рендеринга рисует соответствующую версию в Canvas; то есть, если вы уменьшаете масштаб или растровое изображение недоступно (например, потому что оно загружается в фоновом режиме), то используется версия с пониженной дискретизацией.
- Панорамирование, Fling и Zoom обрабатываются с помощью GestureListeners.
Благодарность принадлежит Джону Ломбардо за первое воплощение идеи, которую я нашел.
Я открыл свою собственную реализацию вместе с некоторыми другими моими вспомогательными классами по адресу https://github.com/micabyte/android_game
Это довольно недавняя реализация, поэтому в настоящее время ее не приняли боевое крещение от реальных пользователей. Тем не менее, я запустил тесты с отображением растровых изображений размером 8000x4000 пикселей и до сих пор не испытывал проблем. Производительность, безусловно, кажется адекватной моим потребностям.
Реализация пинч и масштабирование - это то, что вы бы сделали с комбинацией ScaleGestureDetector и интерфейса Canvas с матрицей преобразования. Вы захотите использовать одну и ту же матрицу преобразования для обработки как масштаба, так и перевода.
Взгляните на пример One Finger Zoom на сайте разработчиков Sony Ericsson. http://developer.sonymobile.com/wp/tag/zoom/