【问题标题】:display huge Images in Android在 Android 中显示巨大的图像
【发布时间】:2011-09-24 23:35:04
【问题描述】:

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

我的第一个解决方案 - 以 pdf 格式提供它们 - 失败了,因为并非每台手持设备都预装了 pdf 查看器,而且我不想要求用户安装一个。

所以我现在有一个我想要显示的 png (width = 3998px height=2827px)。我下载了这张图片来测试它在画廊中的显示方式。这很痛苦。好像图片库只渲染了一次,放大后根本看不懂文字。

所以我写了一个 testActivity,它只是有一个嵌套在 LinearLayout 中的 ImageView。我将图像放入drawable并将其设置为ImageView的图像源。 不幸的是,由于“

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

没想到 ONE single Image 对于VM's memory 来说可能太大了。我玩了一下,将 ImageViews 大小设置为 3998 & 2827px ,将图像设置为 sdCard 并使用 fileInputStream 手动读取。
令我大吃一惊的是,它现在显示了我的图像,但如果我将 Nexus S 水平放置,我会得到与以前相同的 OutOfMemoryError

有人可以指出通过FileInputStream 接收位图或将其设置为ImageView's 源之间的主要区别。

此外,我无法舒适地滚动两个父 scrollViews

我正在寻找一个简单的解决方案来一次显示ONE large image,同时能够放大和缩小scroll horizontal and vertical

这是我要显示的图像示例

【问题讨论】:

    标签: android image memory view png


    【解决方案1】:

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

    适用于 Android 的自定义图像视图,专为照片库和 显示巨大的图像(例如地图和建筑平面图) 内存不足错误。包括捏缩放、平移、旋转和 动画支持,并允许轻松扩展,因此您可以添加自己的 覆盖和触摸事件检测。

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    • 但是这个库不能使用触摸来旋转图像,它只允许旋转 90 度。
    【解决方案2】:

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

     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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        https://github.com/johnnylambada/WorldMap

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

        为了整合,我只是复制了所有的 java 文件(我猜是 5 个)并在我的布局文件中使用了 surfaceView。然后我通过了 ImageViewerActivity.java 的小 OnCreate() 方法,并在我的活动中使用了代码(略有改动,取决于我的个人使用)。

        【讨论】:

          【解决方案5】:

          我知道这是一个老问题,但我使用 TileView 来做到这一点:

          https://github.com/moagrius/TileView

          【讨论】:

            【解决方案6】:

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

            我想显示一张 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);
            
                }
            }
            

            这行得通。

            【讨论】:

            • 不错的解决方案。我现在通过平铺图像找到了一种更好的方法(需要大量编码)。对于不同的 ZoomLevels,我也有 3 个不同质量的相同图片版本。这甚至适用于无法解码原始位图的 1/4 的旧设备
            • 这里的k是什么?希望 widthheight 表示实际图像尺寸。请澄清这一点。
            • Rafael:你不应该(理论上!)需要不同的分辨率版本 - 查看BitmapFactory.Options.inSampleSize
            • @leadersheep : 你能告诉我们这里 k 的价值是什么吗?
            • 这里,我把我的图片分成了 4 个部分,所以 k = 2
            【解决方案7】:

            This post 是一个很好的演示,用于使用多点触控手势缩放图片。它使用 Matrix 来缩放和平移图片。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-11-07
              • 2012-05-15
              • 2012-08-29
              • 1970-01-01
              • 2013-06-19
              相关资源
              最近更新 更多