2011-06-29 221 views
27

我打算在Android中顯示非常大的圖像。

我的第一個解決方案 - 將它們提供爲PDF格式 - 失敗,因爲並非每個手持設備都預裝了pdf查看器,而且我也不想要求用戶安裝一個。在Android中顯示巨大圖像

所以我現在有一個PNG (寬度= 3998px高度= 2827px),我想要顯示。我下載了這張圖片來測試它將如何顯示在畫廊上。這是非常痛苦的。看來這個畫面只會渲染一張圖片,如果我放大,我根本看不懂文字。

所以我寫了一個testActivity,它只是一個嵌入在LinearLayout中的ImageView。我將圖像放入drawable中,並將其設置爲ImageView的圖像源。 Unforunately的應用程序崩潰,立刻,由於「

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

我沒想到的是一個單獨的影像可VM's memory太大。我打得有點左右,設置ImageViews大小3998 & 2827px,就把圖片到sdCard並用fileInputStream手動讀取。
要我很大的驚喜,現在顯示了我的形象,但如果我把我的Nexus S的水平我得到同樣的OutOfMemoryError以前一樣。

能somewone點我的主要區別在rec之間即通過FileInputStream的位圖或將其設置爲ImageView's源。

還有我不能滾動舒服兩個上級scrollViews

我尋找一個簡單的解決方案,在有能力一次顯示ONE large imagescroll horizontal and vertical同時能夠放大和縮小。

這裏是我想要顯示 enter image description here

回答

26

我知道這是一箇舊帖子,但我花了很多時間在這個問題上,所以這是我的解決方案。

我想顯示一個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); 

    } 
} 

這個工作。

+0

好的解決方案。我現在通過平鋪我的圖像找到了一種更好的方式(通過很多編碼工作)。對於不同的縮放級別,我也有不同質量的相同圖片的3個版本。即使在舊設備上,這也無法解碼1/4原始位圖 –

+2

什麼是** k **在這裏?希望**寬度**和**高度**表示實際圖像尺寸。請澄清一下。 – AnujAroshA

+1

拉斐爾:你不應該(在理論上!)需要不同的分辨率版本 - 檢查'BitmapFactory.Options.inSampleSize'。 – Timmmm

2

This post是使用多點觸摸手勢縮放圖片的良好示範。它使用矩陣來縮放以及平移圖片。

4

您可以使用此 「易integerate」 世界地圖應用程序的來源:

https://github.com/johnnylambada/WorldMap

這使用世界地圖的巨大圖像,並使用緩存來顯示地圖。

爲了整合,我只複製了所有的java文件(5我猜),並在我的佈局文件中使用了surfaceView。然後,我瀏覽了ImageViewerActivity.java的小型OnCreate()方法,並在我的活動中使用了代碼(根據我個人的使用情況稍作修改)。

1

要處理縮放等,並使用全分辨率,您可以使用OSM的MapView(打開街道地圖),並提供您的瓷磚(而不是地圖)。檢查:http://www.haakseth.com/?p=30

7

嘗試使用此一: https://github.com/davemorrissey/subsampling-scale-image-view

爲Android定製圖像視圖,專爲照片畫廊和 顯示巨大的圖像(如地圖和建設計劃)沒有 OutOfMemoryErrors。包括捏縮放,平移,旋轉和動畫支持,並允許輕鬆擴展,所以你可以添加自己的 覆蓋和觸摸事件檢測。

+0

雖然這個鏈接可能回答這個問題,但最好在這裏包含答案的重要部分,並提供參考鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 – Kmeixner

+0

但是這個庫不能使用觸摸旋轉圖像,它只允許旋轉90度。 – bebosh