【问题标题】:Load Btimap of Video thumbnails from sdcard从 sd 卡加载视频缩略图的位图
【发布时间】:2016-02-25 10:09:09
【问题描述】:

我正在开发一个模块,我需要在其中以视频缩略图的形式显示手机中的所有视频。我已经使用 BaseAdapter 将所有视频缩略图显示到 GridView 中。唯一的问题是我必须在 BaseAdapter 的 getView() 中编写代码从视频文件中提取缩略图到位图。

 ((Activity) context).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                 Bitmap bmThumbnail = ThumbnailUtils.createVideoThumbnail(
                                                videoValues.get(position).getFile()
                                               .getAbsolutePath(), Thumbnails.MINI_KIND);
                 imageThumbnail.setImageBitmap(bmThumbnail);
                 bmThumbnail = null;
    }
    });

我想用一些图像加载器异步加载它。我已经尝试过 Aquery、Universal Image Loader、Picasso 等,但它们都没有提供带有内存缓存、文件缓存、故障回调机制等的异步图像加载。

谁能建议我如何有效地实现这一目标? TIA。

【问题讨论】:

  • 你找到解决这个问题的办法了吗。
  • @manishkumar - 请在下面查看我的答案。

标签: android performance image-loading video-thumbnails aquery


【解决方案1】:

为了解决这个问题,我开设了一个课程VideoThumbLoader。它异步生成位图并将其传递给适配器。所以主要的好处是整个过程都在后台线程中处理。

类代码如下:

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.support.v4.util.LruCache;
import android.widget.ImageView;

public class VideoThumbLoader {

    private LruCache<String, Bitmap> lruCache;

    @SuppressLint("NewApi")
    public VideoThumbLoader() {
        int maxMemory = (int) Runtime.getRuntime().maxMemory();// obtain maximum
                                                                // memory to run
        int maxSize = maxMemory / 4;// get cache memory size 35
        lruCache = new LruCache<String, Bitmap>(maxSize) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                // this will be called when the cache deposited in each
                return value.getByteCount();
            }
        };
    }

    public void addVideoThumbToCache(String path, Bitmap bitmap) {
        if (getVideoThumbToCache(path) == null && bitmap != null) {

            lruCache.put(path, bitmap);
        }
    }

    public Bitmap getVideoThumbToCache(String path) {

        return lruCache.get(path);
    }

    public void showThumbByAsynctack(String path, ImageView imgview) {

        if (getVideoThumbToCache(path) == null) {
            // asynchronous loading
            new MyBobAsynctack(imgview, path).execute(path);
        } else {
            imgview.setImageBitmap(getVideoThumbToCache(path));
        }
    }

    class MyBobAsynctack extends AsyncTask<String, Void, Bitmap> {
        private ImageView imgView;
        private String path;

        public MyBobAsynctack(ImageView imageView, String path) {
            this.imgView = imageView;
            this.path = path;
        }

        @Override
        protected Bitmap doInBackground(String... params) {

            Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(params[0],
                    MediaStore.Video.Thumbnails.MINI_KIND);

            // provide
            if (getVideoThumbToCache(params[0]) == null) {
                addVideoThumbToCache(path, bitmap);
            }
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (imgView.getTag().equals(path)) {// through Tag can be bound
                                                // pictures address and
                                                // imageView, this address
                                                // Listview loading the image
                                                // dislocation solution
                imgView.setImageBitmap(bitmap);
            }
        }
    }
}

从适配器端,只需调用:

private VideoThumbLoader mVideoThumbLoader = new VideoThumbLoader();
 imageThumbnail.setTag(videoValues.get(position).getFile()
                    .getAbsolutePath());// binding imageview
 imageThumbnail.setImageResource(R.drawable.videothumb); //default image
 mVideoThumbLoader.showThumbByAsynctack(videoValues.get(position)
                    .getFile().getAbsolutePath(), imageThumbnail);

P.S:我注意到的一件重要的事情是,由于位图的异步下载,很少有缩略图容易混淆的情况。所以我用文件路径标记了imageview。这样,我将获得图像的确切缩略图。

【讨论】:

    【解决方案2】:


    使用 SuziLoader

    此加载器将加载本地存储在后台文件系统中的视频的缩略图。

    String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/video.mp4";
    ImageView mThumbnail = (ImageView) findViewById(R.id.thumbnail);
    
    SuziLoader loader = new SuziLoader(); //Create it for once.
    loader.with(MainActivity.this) //Context
        .load(path) //Video path
        .into(mThumbnail) // imageview to load the thumbnail
        .type("mini") // mini or micro
        .show(); // to show the thumbnail
    

    要获得此依赖项,请使用以下步骤

    步骤 1. 将 JitPack 存储库添加到您的构建文件
    将其添加到存储库末尾的根 build.gradle 中:

    allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }
    

    第 2 步。 添加依赖项

    dependencies {
        compile 'com.github.sushinpv:SuziVideoThumbnailLoader:0.1.0'
    }
    

    在清单中添加读取外部存储权限

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    

    【讨论】:

    • 快速滚动图像(例如网格或列表或回收视图)会像随机变化一样自动变化。并让用户感到不安。
    猜你喜欢
    • 2012-03-28
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    相关资源
    最近更新 更多