Работа с ограничениями размера текстуры Android - программирование
Подтвердить что ты не робот

Работа с ограничениями размера текстуры Android

У меня есть требование отображать несколько больших изображений в приложении для Android. Прямо сейчас я использую ImageView с исходным растровым изображением. Я понимаю, что openGL имеет определенное независимое от устройства ограничение насколько велики размеры изображения для его обработки.

Есть ли какой-либо способ отображения этих изображений (с фиксированной шириной, без обрезки) независимо от этого ограничения, кроме разделения изображения на несколько элементов ImageView?

Спасибо.

ОБНОВЛЕНИЕ 01 апреля 2013 г. Пока еще не повезло, все предложения заключались в снижении качества изображения. Один из них предположил, что можно обойти это ограничение, используя CPU для обработки вместо использования графического процессора (хотя может потребоваться больше времени для обработки). Я не понимаю, действительно ли невозможно отображать длинные изображения с фиксированной шириной без снижения качества изображения? Бьюсь об заклад, есть, мне бы это понравилось, если бы кто-нибудь по крайней мере указал мне в правильном направлении.

Спасибо всем.

4b9b3361

Ответ 1

Вы можете использовать BitmapRegionDecoder, чтобы разбить большие растровые изображения (требуется уровень API 10). Я написал метод, который будет использовать этот класс и вернуть один Drawable, который может быть помещен внутри ImageView:

private static final int MAX_SIZE = 1024;

private Drawable createLargeDrawable(int resId) throws IOException {

    InputStream is = getResources().openRawResource(resId);
    BitmapRegionDecoder brd = BitmapRegionDecoder.newInstance(is, true);

    try {
        if (brd.getWidth() <= MAX_SIZE && brd.getHeight() <= MAX_SIZE) {
            return new BitmapDrawable(getResources(), is);
        }

        int rowCount = (int) Math.ceil((float) brd.getHeight() / (float) MAX_SIZE);
        int colCount = (int) Math.ceil((float) brd.getWidth() / (float) MAX_SIZE);

        BitmapDrawable[] drawables = new BitmapDrawable[rowCount * colCount];

        for (int i = 0; i < rowCount; i++) {

            int top = MAX_SIZE * i;
            int bottom = i == rowCount - 1 ? brd.getHeight() : top + MAX_SIZE;

            for (int j = 0; j < colCount; j++) {

                int left = MAX_SIZE * j;
                int right = j == colCount - 1 ? brd.getWidth() : left + MAX_SIZE;

                Bitmap b = brd.decodeRegion(new Rect(left, top, right, bottom), null);
                BitmapDrawable bd = new BitmapDrawable(getResources(), b);
                bd.setGravity(Gravity.TOP | Gravity.LEFT);
                drawables[i * colCount + j] = bd;
            }
        }

        LayerDrawable ld = new LayerDrawable(drawables);
        for (int i = 0; i < rowCount; i++) {
            for (int j = 0; j < colCount; j++) {
                ld.setLayerInset(i * colCount + j, MAX_SIZE * j, MAX_SIZE * i, 0, 0);
            }
        }

        return ld;
    }
    finally {
        brd.recycle();
    }
}

Этот метод будет проверять, будет ли ресурс, который вытягивается, меньше, чем MAX_SIZE (1024) в обеих осях. Если это так, он просто возвращает drawable. Если это не так, это сломает изображение и расшифрует фрагменты изображения и поместит их в LayerDrawable.

Я выбрал 1024, потому что я считаю, что большинство доступных телефонов будут поддерживать изображения, по крайней мере, такие большие. Если вы хотите найти фактический размер размера шрифта для телефона, вы должны сделать некоторые напуганные вещи через OpenGL, и это не то, что я хотел бы погрузиться в.

Я не был уверен, как вы обращались к своим изображениям, поэтому я предположил, что они были в вашей папке. Если это не так, должно быть довольно легко реорганизовать метод для принятия любого параметра, который вам нужен.

Ответ 2

Вы можете использовать BitmapFactoryOptions для уменьшения размера изображения. Вы можете использовать что-то вроде этого:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3; //reduce size 3 times

Ответ 3

Вы видели, как работают ваши карты? Однажды я сделал рендер для карт. Вы можете использовать тот же трюк, чтобы отображать ваше изображение.

Разделите изображение на квадратные плитки (например, 128x128 пикселей). Создайте настраиваемый рендеринг изображений из плит. Ваш imageView знает, какую часть растрового изображения он должен показать сейчас, и отображает только необходимые фрагменты, загружающие их с вашей SD-карты. Используя такую ​​карту плитки, вы можете отображать бесконечные изображения.

Ответ 4

Это поможет, если вы дадите нам размеры вашего растрового изображения.

Пожалуйста, поймите, что OpenGL работает против естественных математических ограничений.

Например, есть очень веская причина, что текстура в OpenGL должна быть равна 2 x. Это действительно единственный способ, с помощью которого математика любого масштабирования может быть выполнена без каких-либо остатков.

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