Android:扫描目录并显示图片(缩略图)(图片不存储在mediastore中)

Android:扫描目录并显示图片(缩略图)(图片不存储在mediastore中),android,android-gallery,Android,Android Gallery,我最近做了一些测试,使用我使用媒体查询和mediastore设计的自定义图库显示图片。。。它工作得很好,但我真的需要做一些定制的事情 我不希望图片被扫描或在mediastore中可用,因此我希望我的应用程序扫描目录,创建缩略图并显示这些缩略图 我发现要找到任何高质量的例子来做这件事实在是太难了 谁能举个小例子来帮助我 这就是我想要做的 图片存储在SD卡的目录中 使用我的自定义库,它将扫描此目录,但“不”使用mediastore 我需要显示目录的内容,但作为缩略图,我想我需要先创建这个缩略图 点击

我最近做了一些测试,使用我使用媒体查询和mediastore设计的自定义图库显示图片。。。它工作得很好,但我真的需要做一些定制的事情

我不希望图片被扫描或在mediastore中可用,因此我希望我的应用程序扫描目录,创建缩略图并显示这些缩略图

我发现要找到任何高质量的例子来做这件事实在是太难了

谁能举个小例子来帮助我

这就是我想要做的

  • 图片存储在SD卡的目录中
  • 使用我的自定义库,它将扫描此目录,但“不”使用mediastore
  • 我需要显示目录的内容,但作为缩略图,我想我需要先创建这个缩略图
  • 点击一个图钉将显示我的自定义图库中的全屏图像
  • 我想我只是需要一些帮助从目录中获取图片,因为没有存储在int eh 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文件
    *@返回
    *@投掷