2012-08-30 50 views
4

我最近使用我設計的使用媒體查詢和媒體存儲的自定義圖庫進行了顯示圖片的一些測試......它的工作原理偉大的,但我真的需要做一些自定義。Android:掃描目錄並顯示圖片(縮略圖)(圖片未存儲在媒體庫中)

我不希望圖片在mediastore中被掃描或可用,因此我想讓我的應用掃描一個目錄並創建縮略圖並顯示這些縮略圖。

我發現它很難找到任何高質量的例子來做到這一點。

任何人都可以幫助一個小例子。

這是我期待的。

  1. 圖片存儲在SD卡的目錄中。
  2. 使用我的自定義庫,它會掃描此目錄,但使用媒體存儲「不」使用
  3. 我需要顯示目錄的內容,但作爲縮略圖,我認爲我需要先創建這個縮略圖?
  4. 點擊thumnail會從我的自定義畫廊的全屏幕圖像。

我想我只是需要一些幫助,從目錄中獲取圖片考慮到沒有存儲int eh mediastore所以我不能使用查詢。另外一件事情是我需要爲每個這些圖像創建縮略圖(在飛行中??),因爲顯示圖像但尺寸減小,我認爲會對性能造成很大的影響。

任何人都可以伸出援手嗎?

在此先感謝

回答

2

我做了完全一樣的前一陣子。您必須將您的圖像所在的文件夾名稱傳遞到setBaseFolder。這種方法依次調用其中refresh() - 使用FilenameFilter(代碼不包括,但很容易實現)獲得命名orig_....jpg從該文件夾中的所有圖像並將其保持在mFileList。然後我們調用notifyDataSetChanged(),這又將觸發getView()爲每個單元格。

現在,getView()我們無論是從取如果我們已經有它存在一個緩存縮略圖位圖,否則我們做一個灰色的佔位符,並開始ThumbnailBuilder創建縮略圖RESP。從它得到一個位圖。

我認爲你必須稍微改變ThumbnailBuilder,因爲我創建了非常大的「縮略圖」(500x500),因爲我還需要爲其他目的調整大小的圖像。另外,由於我使用相機拍攝的照片,因此存在一些內容,根據exif信息旋轉圖像。但基本上,ThumbnailBuilder只是檢查是否存在已是一個縮略圖(我的縮略圖被放置在同一個文件夾,但有前綴small_代替orig_) - 如果縮略圖畫面已經存在,我們把它作爲一個Bitmap和完成,否則圖像生成。最後,在onPostExecute()位圖設置爲ImageView的。

public class PhotoAdapter extends BaseAdapter { 

private Context mContext; 
private int mCellSize; 
private File mFolder; 
private File[] mFileList; 
private Map<Object, Bitmap> mThumbnails = new HashMap<Object, Bitmap>(); 
private Set<Object> mCreatingTriggered = new HashSet<Object>(); // flag that creating already triggered 

public PhotoAdapter(Context context, int cellSize) { 
    mContext = context; 
    mCellSize = cellSize; 
} 

@Override 
public int getCount() { 
    if (mFolder == null) { 
     return 0; // don't do this 
    } else { 
     return mFileList.length; 
    } 
} 

@Override 
public Object getItem(int position) { 
    return mFileList[position]; 
} 

@Override 
public long getItemId(int position) { 
    return position; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    ImageView view = (ImageView)convertView; 
    if (view == null) { 
     view = new ImageView(mContext); 
     view.setLayoutParams(new GridView.LayoutParams(mCellSize, mCellSize)); 
     view.setScaleType(ImageView.ScaleType.CENTER_CROP); 
     view.setPadding(8, 8, 8, 8); 
     view.setBackgroundColor(0xFFC6CCD3); 
    } 
    Object item = getItem(position); 
    Bitmap bm = mThumbnails.get(item); 
    if (bm == null) { 
     view.setImageBitmap(null); 
     if (!mCreatingTriggered.contains(item)) { 
      mCreatingTriggered.add(item); 
      new ThumbnailBuilder(view, (File)item).execute(); 
     } 
    } else { 
     view.setImageBitmap(bm); 
    } 
    return view; 
} 

public void setBaseFolder(File baseFolder) { 
    if (baseFolder == null) return; 
    if (!baseFolder.equals(mFolder)) { 
     releaseThumbnails(); 
     mFolder = baseFolder; 
    } 
    refresh(); 
} 

public void refresh() { 
    if (mFolder == null) { 
     return; 
    } 
    mFileList = mFolder.listFiles(EtbApplication.origImageFilenameFilter); 
    if (mFileList == null) mFileList = new File[0]; 
    notifyDataSetChanged(); 
} 

public void releaseThumbnails() { 
    for (Bitmap bm : mThumbnails.values()) { 
     bm.recycle(); 
    } 
    mThumbnails.clear(); 
} 

// ------------------------------------------------------------------------------------ Asynchronous Thumbnail builder 

private class ThumbnailBuilder extends AsyncTask<Void, Integer, Bitmap> { 

    private ImageView mView; 
    private File mFile; 

    public ThumbnailBuilder(ImageView view, File file) { 
     mView = view; 
     mFile = file; 
    } 

    @Override 
    protected Bitmap doInBackground(Void... params) { 
     Log.d("adapter", "make small image and thumbnail"); 
     try { 
      return createThumbnail(mFile.getAbsolutePath()); 
     } catch (Exception e) { 
      return null; 
     } 
    } 

    @Override 
    protected void onPostExecute(Bitmap result) { 
     if (result != null) { 
      mView.setImageBitmap(result); 
      mThumbnails.put(mFile, result); 
     } else { 
      mView.setImageResource(R.drawable.ic_launcher); 
     } 
    } 

    /** 
    * Creates Thumbnail (also rotates according to exif-info) 
    * @param file 
    * @return 
    * @throws IOException 
    */ 
    private Bitmap createThumbnail(String file) throws IOException { 

     File thumbnailFile = new File(file.replace("orig_", "small_")); 

     // If a small image version already exists, just load it and be done. 
     if (thumbnailFile.exists()) { 
      return BitmapFactory.decodeFile(thumbnailFile.getAbsolutePath()); 
     } 

     // Decode image size 
     BitmapFactory.Options bounds = new BitmapFactory.Options(); 
     bounds.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(file, bounds); 

     if ((bounds.outWidth == -1) || (bounds.outHeight == -1)) 
      return null; 

     int w, h; 

     if (bounds.outWidth > bounds.outHeight) { // Querformat 
      w = 500; 
      h = 500 * bounds.outHeight/bounds.outWidth; 
     } else { // Hochformat 
      h = 500; 
      w = 500 * bounds.outWidth/bounds.outHeight; 
     } 

     BitmapFactory.Options opts = new BitmapFactory.Options(); 
     opts.inSampleSize = 4; // resample -- kleiner aber noch nicht die 500 Pixel, die kommen dann unten 
     Bitmap resizedBitmap = BitmapFactory.decodeFile(file, opts); 
     resizedBitmap = Bitmap.createScaledBitmap(resizedBitmap, w, h, true); 

     ExifInterface exif = new ExifInterface(file); 
     String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION); 
     int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL; 
     int rotationAngle = 0; 
     if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90; 
     if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180; 
     if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270; 

     Matrix matrix = new Matrix(); 
     matrix.setRotate(rotationAngle, (float) resizedBitmap.getWidth()/2, (float) resizedBitmap.getHeight()/2); 
     Bitmap rotatedBitmap = Bitmap.createBitmap(resizedBitmap, 0, 0, w, h, matrix, true); 
     resizedBitmap.recycle(); 
     ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 
     rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes); 

     thumbnailFile.createNewFile(); 
     FileOutputStream fo = new FileOutputStream(thumbnailFile); 
     fo.write(bytes.toByteArray()); 
     fo.close(); 

     //new File(file).delete(); // Originalbild löschen 

     return rotatedBitmap; 
    } 
} 
}