4

私は最近、メディア クエリとメディアストアを使用して設計したカスタム ギャラリーを使用して、表示画像を使用していくつかのテストを行いました。

写真をスキャンしたり、メディアストアで利用したりしたくないので、アプリでディレクトリをスキャンしてサムネイルを作成し、これらのサムネイルを表示したいと思います。

これを行うための優れた品質の例を見つけることは、地面では本当に薄いと思います。

誰でも小さな例を手伝ってもらえますか。

これが私がやろうとしていることです。

  1. 写真はSDカードのディレクトリに保存されます。
  2. カスタム ギャラリーを使用すると、このディレクトリがスキャンされますが、メディアストアを使用するのは「そうではありません」
  3. ディレクトリの内容を表示する必要がありますが、サムネイルとして、最初にこのサムネイルを作成する必要があると思いますか?
  4. サムネイルをクリックすると、カスタム ギャラリーの全画面画像が表示されます。

メディアストアに保存されていないため、クエリを使用できないため、ディレクトリから写真を取得するのに少し助けが必要だと思います。私が懸念するもう1つのことは、これらの画像のそれぞれのサムネイルを(その場で??)作成する必要があるということです.

誰でも手を差し伸べることができますか?

前もって感謝します

4

1 に答える 1

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;
    }
}
}
于 2012-08-30T06:54:37.860 に答える