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

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

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

Спасибо.

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

Всем спасибо.

Вы можете использовать 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 ресурс, меньше MAX_SIZE (1024) в обеих осях. Если это так, он просто возвращает drawable. Если это не так, это сломает изображение и расшифрует фрагменты изображения и поместит их в LayerDrawable .

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

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

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

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

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

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

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

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

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

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