Вторник, 12.12.2017, 09:22
Поиск
Никнэйм
Сертификат на никнейм Olelucoye, зарегистрирован на Тимофеев Константин Михайлович
Зарегистрируй свой никнейм
Обратная связь
olelucoye.tk@yandex.ru
Реклама AdSense
Реклама
Друзья сайта
  • Лига медицинского права
  • Гостиница "Зай"
  • FAQ по системе
  • Инструкции для uCoz
  • Главная » Статьи » libGDX

    libGDX. Создание скриншотов.

    libGDX. Создание скриншотов.

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

    В этом нам поможет метод ScreenUtils.getFrameBufferPixmap, который, как понятно из его имени извлекает картинку из буфера. Нам остается только записать её в файл.

    Создадим класс для записи скриншотов:

       public static class ScreenshotFactory {
            private static int counter = 1;
            public static void saveScreenshot(){
                try{
                    FileHandle fh;
                    do{
                        fh = new FileHandle(Gdx.files.getExternalStoragePath() + "screenshot" + counter++ + ".png");
                    }while (fh.exists());
                    Pixmap pixmap = getScreenshot(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
                    PixmapIO.writePNG(fh, pixmap);
                    pixmap.dispose();
                }catch (Exception e){           
                }
            }
            private static Pixmap getScreenshot(int x, int y, int w, int h, boolean yDown){
                final Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(x, y, w, h);
                if (yDown) {
                    ByteBuffer pixels = pixmap.getPixels();
                    int numBytes = w * h * 4;
                    byte[] lines = new byte[numBytes];
                    int numBytesPerLine = w * 4;
                    for (int i = 0; i < h; i++) {
                        pixels.position((h - i - 1) * numBytesPerLine);
                        pixels.get(lines, i * numBytesPerLine, numBytesPerLine);
                    }
                    pixels.clear();
                    pixels.put(lines);
                }
                return pixmap;
            }
        }

    Ничего сложного. Подготавливаем FileHandle. Gdx.files.getExternalStoragePath() дает нам путь папке для хранения файлов установленной в системе по умолчанию (в Windows7 это будет C:\Users\Имя_Пользователя, в Андроид - домашняя папка \sdcard\). Проверяем на существование, если такой файл существует, увеличиваем нумерацию на 1 до тех пор пока не найдем свободное имя файла. Затем вызываем getScreenshot, передавая координаты начальной точки и размеры (т.е. мы можем получить снимок не всего окна, а только заданной части), а также булеву переменную, в зависимости от которой изображение останется таким как есть или будет перевернуто.

    В getScreenshot получаем изображение из буфера. Затем идет код переворота картинки. Возвращаем картинку.

    Зачем переворачивать картинку? Дело в том, что ось Y камеры в libGDX направлена вниз, поэтому не сделав это, получим картинку вверх ногами.

    Теперь можем назначить нажатию какой-нибудь кнопки создание скриншота (для десктопа):

        @Override
        public boolean keyDown(int keycode) {
           .....
            switch(keycode){
           .....
            case Keys.P:
                ScreenshotFactory.saveScreenshot();
                break;
           .....
            return true;
        }

    Для андроид можно назначить создание скриншота экранной кнопке (я временно использовал для этой цели кнопку прыжка):

         public class TheStage extends Stage{
           public boolean touchDown(int screenX, int screenY, int pointer, int button) {
                screenY = scrY - screenY;
                Actor actor = hit(screenX, screenY, true);
                if(actor == null){
                    aName = "null";
                    return false;
                }else{
                    aName = actor.getName();
                   ....
                    if(aName.equals("jump")){
                        ScreenshotFactory.saveScreenshot();
                    }
                    .....
                    return true;
                }
            }

    Не забываем добавить в Android manifest разрешение на запись:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

    Скриншоты полученные на PC и андроид с разными значениями yDown.

       

    Также можно использовать этот код для получения последовательного ряда изображений, добавив получение скриншота в render.

        int render_count = 0;
        int scr_count = 0;
         .....
        @Override
        public void render () {
            .....
            if(!loading){
                ......
                stage.draw();
                render_count ++;
                if(scr_count < 250 && render_count == 2){
                    ScreenshotFactory.saveScreenshot();
                    render_count = 0;
                    scr_count ++;
                }
            }
        }

    Я сделал так, чтобы скриншот снимался каждый второй цикл и ограничил количество скриншотов числом 250. Запустив приложение получаем 250 хронологически пронумерованных изображений.

    Для чего это всё нужно? Из этих изображений мы можем собрать видеофайл с помощью программы обработки видео (я пользуюсь Virtual dub). Вот что у меня получилось (10 кадров в секунду).

    Большого видео сделать не получится, т.к. процесс создания скриншотов сильно нагружает железо и требует много места на носителе - одно изображение 1280 на 800 занимает 460 Кб, а 250 кадров заняли около 112 Мб. Но для записи демонстрационного ролика достаточно.

    libGDX. Полноэкранный режим. Перехват нажатия кнопок Back и Menu.
    libGDX. Озвучка персонажа.
    libGDX. Анимация персонажа.
    libGDX. Scene2D. Сенсорное управление персонажем.
    libGDX. Scene2D.
    libGDX. Формы столкновений.
    libGDX. Bullet. Динамика твердого тела. Часть 2.
    libGDX. Bullet. Динамика твердого тела.
    libGDX. Обработка столкновений. Библиотека Bullet. Часть 3.
    libGDX. Обработка столкновений. Библиотека Bullet. Часть 2.
    libGDX. Обработка столкновений. Библиотека Bullet.
    libGDX. Интерактивное взаимодействие с 3D объектами.
    libGDX. Отбраковка объектов не попадающих в обзор камеры.
    3D модель  для libGDX. Пишем код.
    3D модель для движка libGDX
    Строим модель с помощью ModelBuilder
    libGDX. Основы 3D программирования.
    Игра Flower. Ловим капли.
    TexturePacker.Создаем атлас текстур.
    Создаем проект на движке libGDX

     

    Категория: libGDX | Добавил: Olelucoye (28.06.2015)
    Просмотров: 970
    | Теги: libGDX, Screenshot, pixmap, Скриншот | Рейтинг: 0.0/0
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Меню сайта
    Категории раздела
    Андроид разработка [23]
    libGDX [24]
    Мои андроид проекты [6]
    Excel [7]
    Железяки [5]
    Скрипты в блокноте [4]
    Разное [1]
    Форма входа
    Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    Яндекс Метрика
    Яндекс.Метрика