在Android中显示巨大的图像

发布于 2024-11-17 11:02:16 字数 1057 浏览 4 评论 0原文

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

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

所以我现在有一个想要显示的 png (width = 3998px height=2827px) 。我下载了这张图片来测试它在图库中的显示方式。这是相当痛苦的。画廊似乎只渲染了这张图片一次,如果我放大,我根本无法阅读文字。

所以我写了一个 testActivity,它只是将 ImageView 嵌套在 LinearLayout 中。我将图像放入可绘制对象中并将其设置为 ImageView 的图像源。 不幸的是,应用程序立即崩溃,由于“

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

我没想到单个图像对于VM的内存来说太大了。我玩了一下,设置了ImageViews大小为 3998 & 2827px ,将图像放入 sdCard 并使用 fileInputStream 手动读取。
令我惊讶的是,它现在显示了我的图像,但如果我将 Nexus S 水平转动,我会得到与以前相同的 OutOfMemoryError

有人可以告诉我通过 FileInputStream 接收位图或将其设置为 ImageView 源的主要区别吗?

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

我正在寻找一种简单的解决方案,可以一次显示一张大图像,并且能够水平和垂直滚动,同时能够放大和缩小。

这是我要显示的图像示例 在此处输入图像描述

I'm intending to display very large Images in Android.

My first solution - to supply them as pdf - fails because not every handheld got a pdf-viewer preinstalled, and I don't want to require the users to install one.

So I have a png now (width = 3998px height=2827px) that I want to display. I downloaded this image to test how it would be displayed the gallery. It was quite painful. It seems that the galery renders this picture only once, and if I Zoom in, I cannot read the text at all.

So I wrote a testActivity which simply has an ImageView nested in a LinearLayout. I put the image into the drawable and set it as ImageView's image-source.
Unforunately the app crashes immediatly, due to an "

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

I didn't expect that ONE single Image can be too large forVM's memory. I played a little bit around, set ImageViews size to 3998 & 2827px , put the Image to sdCard and read it manually with a fileInputStream.
To my big surprise it now shows my image, but if I turn my Nexus S horizontal I get the same OutOfMemoryError as before.

Can somewone point me the main difference between recieving a Bitmap through a FileInputStream or to set it as ImageView's source.

Also I'm not able to scroll comfortable with two parent scrollViews

I searching for a simple solution to display ONE large image at a time with the ability to scroll horizontal and vertical while able to zoom in and out.

here is a sample of the image I want to display
enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

眼角的笑意。 2024-11-24 11:02:16

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

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

    }
}

这有效。

I know it's an old post but I spent a lot of time on this problem, so here's my solution.

I wanted to display a 2000×3000 picture but I got out of memory or the image was too large to be displayed.

To begin, I get the dimensions of the picture:

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

Then I cut it up into four parts and displayed them with four ImageViews.
I tried to load the full picture and cut it into four (using BitmapFactory.create(bitmap,int,int,int,int)) but got out of memory again.

So I decided to use some 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);

    }
}

This worked.

蓝海似她心 2024-11-24 11:02:16

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

https://github.com/moagrius/TileView

I know its an old question but I used TileView to do exactly this:

https://github.com/moagrius/TileView

不奢求什么 2024-11-24 11:02:16

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

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

Try to use this one:
https://github.com/davemorrissey/subsampling-scale-image-view

A custom image view for Android, designed for photo galleries and
displaying huge images (e.g. maps and building plans) without
OutOfMemoryErrors. Includes pinch to zoom, panning, rotation and
animation support, and allows easy extension so you can add your own
overlays and touch event detection.

信愁 2024-11-24 11:02:16

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

https://github.com/johnnylambada/WorldMap

这里使用了一张巨大的世界地图图片,并使用缓存来显示地图。

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

You can use this "easy to integerate" source of WorldMap application:

https://github.com/johnnylambada/WorldMap

This uses a huge image of a world map, and uses cache to display a map.

To integerate, I just copied all the java files (5 i guess) and used the surfaceView in my layout file. Then I went through the small OnCreate() method of ImageViewerActivity.java and used the code in my activity (with sligh alteration, depending on my personal use).

贪恋 2024-11-24 11:02:16

这篇文章是一个使用多点触摸手势缩放图片的很好的演示。它使用 Matrix 来缩放和平移图片。

This post is a good demo for zooming a picture using multi touch gestures. It uses Matrix to zoom as well as pan a picture.

等风来 2024-11-24 11:02:16

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

To handle scaling etc and using full resolution, You can use MapView of OSM (open street map) and provide it with your tiles (instead of the map). Check this: http://www.haakseth.com/?p=30

不美如何 2024-11-24 11:02:16

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

 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

We have to follow following steps to remove out of memory exception while loading huge images:

 1. Read Bitmap Dimensions and Type

 2. Load a Scaled down version into memory

Android Developer's Guide defines how we achieve these.
here is the link

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文