Отображать огромные изображения в Android

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

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

Теперь у меня есть png (width = 3998px height=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 в то время как в состоянии увеличивать и уменьшать масштаб.

вот образец изображения, которое я хочу отобразить

7 ответов

Решение

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

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

Для начала я получу размеры картины:

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

Затем я разрезал его на четыре части и отобразил их с четырьмя изображениями. Я попытался загрузить полную картинку и разрезать ее на четыре (используя 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);

    }
}

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

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

https://github.com/moagrius/TileView

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

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

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

https://github.com/johnnylambada/WorldMap

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

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

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

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

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

 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

Другие вопросы по тегам