13

I want to select a video from my Gallery. It's working fine. But now I want to display a Bitmap, as a thumbnail.I tried this code and it's not working, it always says: NullPointerException

Bitmap bitmap2 = ThumbnailUtils.createVideoThumbnail(uri.getPath, MediaStore.Video.Thumbnails.MICRO_KIND);

This is all in an onActivityResult().

How can I get the Bitmap from the video Uri??

Thanks for your help

Vivek Thummar
  • 395
  • 4
  • 17
Zocker Bros
  • 173
  • 1
  • 1
  • 9

8 Answers8

24

In the latest API 24, you may face some issues if you stick with an approach in the accepted answer.

for example in this line int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); sometimes I got W/System.err: java.lang.IllegalArgumentException: column '_data' does not exist error message.

also in the latest API, you may get SecurityException if you deal with widgets or shared content. Keep that in mind.

As for the video thumbnail from Uri - I use an approach which utilizes MediaMetadataRetriever, thus you don't need to get String filePath:

            MediaMetadataRetriever mMMR = new MediaMetadataRetriever();
            mMMR.setDataSource(context, videoUri);
            bmp = mMMR.getFrameAtTime();

Hope this helps

Kirill Karmazin
  • 6,256
  • 2
  • 54
  • 42
  • 1
    if you listen to commonsware this should be along the lines of the best approach... we shouldn't be dealing with files or absolute paths we should be dealing with content uri's that can be accessed through content providers... – me_ Nov 16 '18 at 10:11
  • can we get the thumbnails that galleries are showing? i mean google photos app shows different thumb can we get the exact same thumb? – Mateen Chaudhry Nov 03 '20 at 07:10
  • This is working well, I was trying to put a number in getFrameAtTime which was giving a black image, seems you have to leave it blank.. thanks – DragonFire Jul 05 '21 at 03:26
16

in onActivityResult

String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(uri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();

Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(picturePath, MediaStore.Video.Thumbnails.MICRO_KIND);

Edit

Kotlin version

val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
val cursor = context.contentResolver.query(uri, filePathColumn, null, null, null)
cursor.moveToFirst()

val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val picturePath = cursor.getString(columnIndex)
cursor.close()

val bitmap = ThumbnailUtils.createVideoThumbnail(picturePath, MediaStore.Video.Thumbnails.MICRO_KIND)
shinilms
  • 1,494
  • 3
  • 22
  • 35
  • Happy to help you. – shinilms May 22 '17 at 10:21
  • 1
    Shouldn't it be `MediaStore.Video.Media.DATA`? It's the same value but for the sake of strictness... – algrid Sep 22 '17 at 09:41
  • 1
    It don't work with Android 26. The error is: "Caused by: android.database.CursorIndexOutOfBoundsException: Requested column: -1, # of columns: 0". Any idea? – mary Nov 14 '17 at 17:00
  • I've checked on api 26 and it's working for me. Can you elaborate your problem? – shinilms Nov 15 '17 at 05:50
  • 1
    The uri of my video file has this format: "content://{appId}.fileprovider/external_files/Android/data/{appId}/files/789080a6-0ee1-4efd-8b2a-dd6869be593f". The query doesn't find the file so columnIndex is -1; Any idea for this problem? – mary Nov 15 '17 at 09:02
  • try changing your uri from `content://{appId}.fileprovider/external_files/Android/data/‌​{appId}/files/789080‌​a6-0ee1-4efd-8b2a-dd‌​6869be593f` to `/Android/data/‌​{appId}/files/789080‌​a6-0ee1-4efd-8b2a-dd‌​6869be593f` – shinilms Nov 15 '17 at 09:39
  • 1
    If I change my uri in this way, cursor is null. – mary Nov 15 '17 at 10:27
  • try this `String picturePath = "/Android/data/‌​{appId}/files/789080‌​a6-0ee1-4efd-8b2a-dd‌​6869be593f";` `Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(picturePath, MediaStore.Video.Thumbnails.MICRO_KIND);` – shinilms Nov 15 '17 at 10:51
  • 2
    bitmap is null. – mary Nov 15 '17 at 11:23
  • Bitmap bitmap2 = ThumbnailUtils.createVideoThumbnail(String.valueOf(uriArrayList.get(position).getMedia_uri()), MediaStore.Video.Thumbnails.MICRO_KIND); >> here am trying to get video thumb .still i get empty bitmap. – prakash Mp Oct 23 '18 at 10:03
5

Try this one:

Bitmap bitmap2 = ThumbnailUtils.createVideoThumbnail( uri.getPath() , MediaStore.Images.Thumbnails.MINI_KIND );
me_
  • 681
  • 1
  • 8
  • 18
Junaid Fahad
  • 149
  • 7
2

For API 27, for document URI (1000 is microseconds)

MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource( context, doc_uri );
Bitmap bm = mmr.getScaledFrameAtTime( 1000, MediaMetadataRetriever.OPTION_NEXT_SYNC, 128, 128 );
Style-7
  • 985
  • 12
  • 27
0

This works for me:

Bitmap thumb = ThumbnailUtils.createVideoThumbnail(filePath, Thumbnails.MINI_KIND);

Using ThumbnailUtils, you can create thumbnail of two types.

MediaStore.Images.Thumbnails.MICRO_KIND - type will generate thumbnail of size 96 x 96. MediaStore.Images.Thumbnails.MINI_KIND - type will generate thumbnail of size 512 x 384.

Micer
  • 8,731
  • 3
  • 79
  • 73
kishan verma
  • 984
  • 15
  • 17
0
  1. createVideoThumbnail() needs the file path, not the content uri.
  2. The file path requires external read permissions.

If you're getting null responses, it may be from using the content uri (though the assumption in ThumbnailsUtils.java is of a corrupt video file). When I fixed that, then I was getting permissions errors.

I was able to get the file path from the content uri using the video's ID like this:

val selection = MediaStore.Video.Media._ID + " = $id"
val cursor = 
this.contentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, 
selection, null, null)      

And then continue on with the cursor as in the other answers in SO.

Docs for contentResolver.query()

tnJed
  • 838
  • 9
  • 12
0
Cursor c = MediaStore.Video.query(cr,uri, new String[]{
    MediaStore.Video.VideoColumns._ID,
    MediaStore.Video.VideoColumns.DATA});
if (c!=null){
    c.moveToFirst();
    int id = Integer.valueOf( c.getString(0) );
    c.close();
    BitmapFactory.Options options=new BitmapFactory.Options();
    options.inSampleSize = 1;
    try {
        return MediaStore.Video.Thumbnails.getThumbnail(cr, id, MediaStore.Video.Thumbnails.MINI_KIND, options);
    }catch (java.lang.SecurityException ex){
        ex.printStackTrace();
        //TODO: add create ThumbnailUtils.createVideoThumbnail
        return null;
    }
}
  • 1
    Thank you for this code snippet, which might provide some limited, immediate help. A [proper explanation](https://meta.stackexchange.com/q/114762/349538) would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you’ve made. – Dwhitz Apr 09 '19 at 14:29
0

CancellationSignal ca = new CancellationSignal();

var vthumb = ThumbnailUtils.createVideoThumbnail(new File(value),new Size(120,120), ca);