отображать огромные изображения в Android - PullRequest
29 голосов
/ 29 июня 2011

Я собираюсь отобразить очень большие изображения в Android.

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

Итак, теперь у меня есть png (ширина = 3998px высота = 2827px) , который я хочу отобразить.Я скачал это изображение, чтобы проверить, как оно будет отображаться в галерее.Это было довольно больно.Кажется, что галерея отображает эту картинку только один раз, и если я увеличу масштаб, я вообще не смогу прочитать текст.

Поэтому я написал testActivity, в котором просто имеется ImageView, вложенное в LinearLayout.Я поместил изображение в drawable и установил его как источник изображения ImageView.К сожалению, приложение мгновенно завершает работу из-за "

 ERROR/AndroidRuntime(8906): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget"  

. Я не ожидал, что ОДНО одиночное изображение может быть слишком большим для VM's memory. Я немного поиграл, установив размер ImageViews в3998 & 2827px, поместите изображение в sdCard и прочитайте его вручную с помощью fileInputStream.
К моему большому удивлению, теперь оно показывает мое изображение, но если я поверну Nexus S по горизонтали , я получутот же OutOfMemoryError, что и раньше.

Может ли кто-нибудь указать мне основное различие между получением растрового изображения через FileInputStream или установкой его в качестве ImageView's источника.

Также яне могу удобно прокручивать с двумя родителями scrollViews

Я искал простое решение для отображения ONE large image одновременно с возможностью scroll horizontal and vertical при возможности увеличения и уменьшения.

вот пример изображения, которое я хочу отобразить enter image description here

Ответы [ 7 ]

29 голосов
/ 28 августа 2012

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

Я хотел отобразить изображение 2000 × 3000, но мне не хватило памяти, или изображение былослишком большой для отображения.

Для начала я получаю размеры изображения:

o = new BitmapFactory.Options();
o.inJustDecodeBounds=true;
pictures = BitmapFactory.decodeStream(new FileInputStream(f), null, o);

Затем я разрезал его на четыре части и отобразил их с четырьмя ImageViews.Я попытался загрузить полную картинку и разрезать ее на четыре (используя BitmapFactory.create(bitmap,int,int,int,int)), но снова вышел из памяти.

Поэтому я решил использовать BitMapRegionDecoder:

for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
        ImageView iv = new ImageView(this);         
        InputStream istream =   null;
        try {
         istream = this.getContentResolver().openInputStream(Uri.fromFile(f));
        } catch (FileNotFoundException e1) {
         e1.printStackTrace();
        }
        BitmapRegionDecoder decoder     =   null;
        try {
        decoder = BitmapRegionDecoder.newInstance(istream, false);
        } catch (IOException e) {
                    e.printStackTrace();
        }
    int nw = (j*width/k);
    int nh = (i*height/k);

    Bitmap bMap = decoder.decodeRegion(new Rect(nw,nh, (nw+width/k),(nh+height/k)), null);    
    iv.setImageBitmap(bMap);

    }
}

Это сработало.

7 голосов
/ 25 мая 2015

Попробуйте использовать это: https://github.com/davemorrissey/subsampling-scale-image-view

Пользовательский вид изображения для Android, предназначенный для фото-галерей и отображение огромных изображений (например, карт и планов зданий) без OutOfMemoryErrors. Включает масштабирование, масштабирование, панорамирование, вращение и поддержка анимации, и позволяет легко расширить, так что вы можете добавить свой собственный наложение и обнаружение сенсорного события.

7 голосов
/ 27 ноября 2013

Я знаю, это старый вопрос, но я использовал TileView, чтобы сделать именно это:

https://github.com/moagrius/TileView

4 голосов
/ 21 февраля 2014

Вы можете использовать этот «легко интегрируемый» источник приложения WorldMap:

https://github.com/johnnylambada/WorldMap

Это использует огромное изображение карты мира и использует кэш для отображения карты.

Чтобы объединиться, я просто скопировал все файлы Java (5, я думаю) и использовал surfaceView в моем файле макета.Затем я прошел небольшой метод OnCreate () в ImageViewerActivity.java и использовал код в своей деятельности (с незначительными изменениями, в зависимости от моего личного использования).

2 голосов
/ 30 мая 2012

Этот пост - хорошая демонстрация для увеличения изображения с помощью мультитач жестов. Он использует матрицу для увеличения и панорамирования изображения.

1 голос
/ 28 апреля 2015

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

 1. Read Bitmap Dimensions and Type

 2. Load a Scaled down version into memory

Руководство разработчика Android определяет, как мы этого достигаем.вот ссылка

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap

1 голос
/ 05 июня 2014

Чтобы справиться с масштабированием и т. Д. И с использованием полного разрешения, вы можете использовать MapView OSM (открыть карту улиц) и предоставить его вашим плиткам (вместо карты).Проверьте это: http://www.haakseth.com/?p=30

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...