我最近做了一些测试使用,我利用媒体查询和mediastore设计定制的画廊显示图片...它的工作很好,但我真的需要做一些定制。
我不希望图片在mediastore扫描或可用因此,我想有我的应用程序扫描目录,并创建缩略图和显示这些缩略图。
我发现它真的在地面上薄找到任何很好的例子品质做到这一点。
任何人都可以帮助一个小例子。
这是我所期待的事情。
- 照片存储在SD卡中的目录。
- 使用我的自定义库会扫描这个目录,但“不”使用mediastore
- 我需要显示该目录的内容,但为缩略图我相信我会需要创建这个缩略图第一?
- 点击一个略图应该会从我的自定义库的完整画面。
我想我只需要在得到从目录中的图片考虑有没有存储INT诶mediastore,所以我不能使用查询一点帮助。 我所关心的另一件事是,我需要创建缩略图为每个这些图像的(上飞?),因为显示的图像,但在缩小的尺寸我怀疑将是性能非常糟糕。
任何人都可以伸出援助之手?
提前致谢
我做了完全一样的前一阵子。 你必须通过您的图像到一个文件夹名setBaseFolder
。 这种方法依次调用refresh()
其中-使用FilenameFilter
(不包括代码,但很容易实现)获得命名的所有图像orig_....jpg
从该文件夹并将其保持在mFileList
。 然后我们调用notifyDataSetChanged()
这反过来会触发getView()
的每一个细胞。
现在,在getView()
我们无论是从取如果我们已经有它存在一个缓存缩略图位图,否则我们做一个灰色的占位符,并开始ThumbnailBuilder
创建缩略图RESP。 从它那里得到的位图。
我认为你必须改变ThumbnailBuilder
了一下,因为我创造相当大的“缩略图”(500×500),因为我需要为其他目的而缩放后的图像了。 此外,如我在由摄影机拍摄的照片的工作有一些东西在那里,根据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;
}
}
}
文章来源: Android: Scanning a directory and displaying pictures (thumbnails) (pictures are not stored in the mediastore)