Android:扫描目录并显示图片(缩略图)(图片不存储在mediastore中)
我最近做了一些测试,使用我使用媒体查询和mediastore设计的自定义图库显示图片。。。它工作得很好,但我真的需要做一些定制的事情 我不希望图片被扫描或在mediastore中可用,因此我希望我的应用程序扫描目录,创建缩略图并显示这些缩略图 我发现要找到任何高质量的例子来做这件事实在是太难了 谁能举个小例子来帮助我 这就是我想要做的Android:扫描目录并显示图片(缩略图)(图片不存储在mediastore中),android,android-gallery,Android,Android Gallery,我最近做了一些测试,使用我使用媒体查询和mediastore设计的自定义图库显示图片。。。它工作得很好,但我真的需要做一些定制的事情 我不希望图片被扫描或在mediastore中可用,因此我希望我的应用程序扫描目录,创建缩略图并显示这些缩略图 我发现要找到任何高质量的例子来做这件事实在是太难了 谁能举个小例子来帮助我 这就是我想要做的 图片存储在SD卡的目录中 使用我的自定义库,它将扫描此目录,但“不”使用mediastore 我需要显示目录的内容,但作为缩略图,我想我需要先创建这个缩略图 点击
提前谢谢我刚才也做了同样的事。您必须将图像所在的文件夹名传递给
setBaseFolder
。此方法依次调用refresh()
,该方法使用FilenameFilter
(代码未包含但很容易实现)从该文件夹中获取所有名为orig_…jpg
的图像,并将其保存在mFileList
中。然后我们调用notifyDataSetChanged()
,这反过来会为每个单元格触发getView()
现在,在getView()
中,如果缓存中已经有缩略图位图,我们要么从缓存中获取它,要么创建一个灰色占位符并启动ThumbnailBuilder
来创建缩略图。从中获取位图
我想您必须稍微更改一下ThumbnailBuilder
,因为我创建了相当大的“缩略图”(500x500),因为我还需要调整大小的图像用于其他用途。另外,当我处理相机拍摄的照片时,那里有一些东西,根据exif信息旋转图像。但基本上,ThumbnailBuilder
只是检查是否已经存在缩略图(我的缩略图放在同一文件夹中,但前缀是small\u
而不是orig\u
)-如果缩略图已经存在,我们将其作为位图获取并完成,否则将生成图像。最后,在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;
}
}
}
公共类PhotoAdapter扩展了BaseAdapter{
私有上下文;
私有的整数mCellSize;
私有文件文件夹;
私有文件[]mFileList;
私有映射mThumbnails=newhashmap();
private Set mcreatingtrigger=new HashSet();//创建已触发的标记
公共PhotoAdapter(上下文,int cellSize){
mContext=上下文;
mCellSize=细胞大小;
}
@凌驾
public int getCount(){
if(mFolder==null){
返回0;//不执行此操作
}否则{
返回mFileList.length;
}
}
@凌驾
公共对象getItem(int位置){
返回mFileList[位置];
}
@凌驾
公共长getItemId(int位置){
返回位置;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
ImageView视图=(ImageView)convertView;
如果(视图==null){
视图=新图像视图(mContext);
view.setLayoutParams(新的GridView.LayoutParams(mCellSize,mCellSize));
view.setScaleType(ImageView.ScaleType.CENTER\U裁剪);
视图。设置填充(8,8,8,8);
视图.setBackgroundColor(0xFFC6CCD3);
}
对象项=获取项(位置);
位图bm=mThumbnails.get(项);
如果(bm==null){
view.setImageBitmap(空);
如果(!mCreatingTriggered.contains(项)){
mCreatingTriggered.add(项目);
新建ThumbnailBuilder(视图,(文件)项).execute();
}
}否则{
view.setImageBitmap(bm);
}
返回视图;
}
公用文件夹(文件基文件夹){
如果(baseFolder==null)返回;
如果(!baseFolder.equals(mFolder)){
释放缩略图();
mFolder=baseFolder;
}
刷新();
}
公共无效刷新(){
if(mFolder==null){
返回;
}
mFileList=mFolder.listFiles(EtbApplication.origImageFilenameFilter);
如果(mFileList==null)mFileList=新文件[0];
notifyDataSetChanged();
}
公共无效发布缩略图(){
对于(位图bm:mThumbnails.values()){
bm.recycle();
}
mThumbnails.clear();
}
//----------------------------------------------------------------异步缩略图生成器
私有类ThumbnailBuilder扩展异步任务{
私有图像视图;
私有文件文件;
公共ThumbnailBuilder(图像视图、文件文件){
mView=视图;
mFile=文件;
}
@凌驾
受保护位图doInBackground(无效…参数){
Log.d(“适配器”,“制作小图像和缩略图”);
试一试{
返回createThumbnail(mFile.getAbsolutePath());
}捕获(例外e){
返回null;
}
}
@凌驾
受保护的void onPostExecute(位图结果){
如果(结果!=null){
mView.setImageBitmap(结果);
mThumbnails.put(mFile,result);
}否则{
mView.setImageResource(R.drawable.ic_启动器);
}
}
/**
*创建缩略图(也根据exif信息旋转)
*@param文件
*@返回
*@投掷