在Android中显示巨大的图像

时间:2011-06-29 09:11:46

标签: android image memory view png

我打算在Android中显示非常大的图片。

我的第一个解决方案 - 将它们作为pdf提供 - 失败,因为并非所有掌上电脑都预装了pdf-viewer,我不想要求用户安装一个。

所以我想要显示一个png (width = 3998px height = 2827px)。我下载了这张图片来测试它将如何显示在图库中。这真是太痛苦了。似乎galery只渲染了这张照片一次,如果我放大,我根本无法阅读文字。

所以我写了一个testActivity,它只是一个嵌套在LinearLayout中的ImageView。我将图像放入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 个答案:

答案 0 :(得分:29)

我知道这是一个老帖子,但我花了很多时间来解决这个问题,所以这是我的解决方案。

我想要显示一张2000×3000的照片,但是内存不足或图片太大而无法显示。

首先,我得到图片的尺寸:

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

然后我将其分成四个部分,并用四个ImageView显示它们。 我试图加载完整的图片并将其切成四个(使用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);

    }
}

这很有用。

答案 1 :(得分:7)

我知道这是一个老问题,但我使用TileView来完成这个:

https://github.com/moagrius/TileView

答案 2 :(得分:7)

尝试使用这个: https://github.com/davemorrissey/subsampling-scale-image-view

  

适用于Android的自定义图片视图,专为照片库而设计   没有显示巨大的图像(例如地图和建筑计划)   OutOfMemoryError异常。包括缩放,平移,旋转和   动画支持,并允许轻松扩展,以便您可以添加自己的   叠加和触摸事件检测。

答案 3 :(得分:4)

您可以使用WorldMap应用程序的“易于整合”来源:

https://github.com/johnnylambada/WorldMap

它使用世界地图的巨大图像,并使用缓存来显示地图。

为了整合,我只是复制了所有的java文件(我猜是5)并在我的布局文件中使用了surfaceView。然后我经历了ImageViewerActivity.java的小OnCreate()方法,并在我的活动中使用了代码(根据我的个人用途进行了改变)。

答案 4 :(得分:2)

This post是使用多点触控手势缩放图片的好演示。它使用矩阵进行缩放以及平移图片。

答案 5 :(得分:1)

要处理缩放等并使用全分辨率,您可以使用OSM的MapView(打开街道地图)并提供您的图块(而不是地图)。检查一下:http://www.haakseth.com/?p=30

答案 6 :(得分:1)

我们必须按照以下步骤在加载大图像时删除内存不足异常:

 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