4

目前我正在製作一個應用程序來顯示SD卡圖像。基本上,您可以製作一張專輯併爲其添加圖片,無論它來自MediaStore選取器的相機。如何實現圖片庫(本地圖像)

我試圖實現2種方法:

  1. 用自定義BaseAdapter標準庫的應用程序返回一個視圖
  2. 定製PagerAdapter一個viewpager

我不想顯示網格視圖,所以它應該馬上全屏。之後,我想禁用左右滑動,只能聽取點擊。

Atm這兩種方法都以縱向模式工作。當我切換到風景一些圖像只是下降

03-20 12:20:56.515: W/OpenGLRenderer(17398): Bitmap too large to be uploaded into a texture 

其次是內存不足的錯誤。堆棧溢出如果存在關於OOM和庫的問題,則應該回收視圖以使其工作,因爲convertView始終爲null,不能從BaseAdapter的getView中使用。

所以我用了一個回收站的意見,我限制它的2個視圖和肖像模式工作方法1(使用畫廊)。風景仍然給我同樣的問題。

對於方法2(viewflipper)它處理由

@Override 
public void destroyItem(ViewGroup container, int position, Object object) { 

意見至極永遠不會順便說一句叫...但是縱向模式在這裏工作。景觀仍然崩潰。

我對得到的位圖方法:

public static Bitmap getBitmap(Context ctx, int imageId, ImageView target) { 

    String file = getPath(ctx, imageId); 

    BitmapFactory.Options bmOptions = new BitmapFactory.Options(); 
    bmOptions.inJustDecodeBounds = true; 

    BitmapFactory.decodeFile(file, bmOptions); 
    WindowManager mgr = (WindowManager)   ctx.getSystemService(Context.WINDOW_SERVICE); 

    int scaleFactor = 1; 

    if (mgr != null) { 
     // Get the dimensions of the View 
     int targetW = mgr.getDefaultDisplay().getWidth(); 
     int targetH = mgr.getDefaultDisplay().getHeight(); 
     Log.d(TAG, "Image width + height=" + targetW + "," + targetH); 


     int photoW = bmOptions.outWidth; 
     int photoH = bmOptions.outHeight; 
     // Determine how much to scale down the image 
     scaleFactor = Math.min(photoW/targetW, photoH/targetH); 

    } else { 
     Log.d(TAG, "Target is null"); 
    } 

    // Get the dimensions of the bitmap 
    // Decode the image file into a Bitmap sized to fill the View 
    bmOptions.inJustDecodeBounds = false; 
    bmOptions.inSampleSize = scaleFactor; 
    bmOptions.inPurgeable = true; 
    logHeap(ImageHelper.class); 

    Bitmap bm = BitmapFactory.decodeFile(file, bmOptions); 

    if (target != null) { 
     target.setImageBitmap(bm); 
    } 
    return bm; 
} 

做工精細,我知道我用的窗口管理器,以獲得一個屏幕尺寸,但是那是因爲我的ImageView的仍然是大小(0,0)時,我就膨脹。後來我打電話

imgView.setLayoutParams(new Gallery.LayoutParams(
      Gallery.LayoutParams.FILL_PARENT, 
      Gallery.LayoutParams.FILL_PARENT)); 
    imgView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); 

似乎沒有任何工作...

請注意,我不使用可繪製或包含在APK任何其他資源。 此畫廊應能夠以任何質量加載SD卡或相機中的圖片。很顯然,畫廊應該能夠處理與目錄中一樣多的圖像。

請問有人能幫我解決以下問題嗎?

  1. 有什麼辦法讓默認的畫廊馬上全屏,並阻止網格視圖?這樣我只需要一個適配器來提供圖像,而不是自己製作視圖。 (也許這解決了OOM崩潰)
  2. 我的位圖解碼功能是否正常?我是否需要建立一些黑客來捕捉景觀變化?
  3. 什麼是使用viewpager或gallery來製作我需要的那種畫廊的最佳方式?
  4. 有沒有人有一個全屏畫廊不崩潰的示例代碼?
+0

你想創建一個圖庫或試圖訪問圖庫?解碼邏輯看起來也很好。 – lokoko 2013-01-31 07:55:36

回答

1

這是我過去遇到過幾次的問題。 Google實際上發佈了一篇關於此的文章。

問題出在你用來解碼圖像的inSampleSize中。由於不同的設備具有不同的屏幕和內存大小(VM堆大小可能會從12到64或更多Mb),因此無法以相同方式對所有圖像進行解碼。例如,具有12Mb堆內存的320x240設備中的圖像應該在給定的inSampleSize中給出,而1280x720 64Mb堆內存設備應該使用另一個inSampleSize(較大的一個)。

我攻擊的文章顯示了一種有效的方法來呈現給定的高度和寬度的圖像。請特別注意最後一段代碼段,它們「預先打開」文件並在稍後計算「全解碼」的inSampleSize。

我也想補充一下這個建議。

  1. 使用「getBitmap」功能以異步方式,調用一個新的線程或的AsyncTask(這樣做是因爲使用SD需要時間,這會導致應用程序掛,是緩慢的,給予對中低端設備不好的印象

  2. 試着總是使用相同的位圖對象避免創建多個「位圖位圖=新的位圖()」你必須認識到,加載的位圖存儲在內存中,一旦分配以查看垃圾收集器的「更難」

  3. 當您完成使用Bitma p使它爲空。對此,想象一下你擁有12Mb的最大堆RAM。你的應用程序現在正在使用8Mb。垃圾收集器啓動,無法獲得更多未使用的RAM。您將10個位圖快速分配到ImageView後不會使它們爲空,並且保留其參考。因爲每個位圖都需要500Kb的Ram,所以你的應用會崩潰。使用後始終使Bitmaps爲空。 (你可以通過eclipse訪問它來調試和查看你的內存使用情況,你也可以強制垃圾收集來查看你的應用程序的行爲)。