0

I want to detect and display most recent images and it should be either animated or static images on user choice. Also cannot depend on extentions.Because

  • There would be absence of extention
  • webp images could be animated or static with same extention (.webp)
  • It could be wrong extentions

Is there way to identify whether images are animated (webp, gif, apng) or static (jpg, png, webp, etc)?

private static final String[] COLUMNS_OF_INTEREST = new String[]
{
        MediaStore.Video.Media._ID,
        MediaStore.Video.Media.DATA,
        MediaStore.Video.Media.DISPLAY_NAME,
        MediaStore.Video.Media.SIZE,
        MediaStore.Video.Media.WIDTH,
        MediaStore.Video.Media.HEIGHT,
        MediaStore.Video.Media.DATE_ADDED
};

public void printGifUri(Context context)
{
    ContentResolver cr = context.getContentResolver();

    String selection = MediaStore.Images.Media.MIME_TYPE + "=?";
    String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("webp");
    String[] selectionArgsPdf = new String[]{ mimeType };

    Cursor gifCursor = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, COLUMNS_OF_INTEREST, selection,selectionArgsPdf,
            MediaStore.Images.Media.DATE_ADDED + " DESC");

    gifCursor.moveToFirst();
    int columnIndexUri = gifCursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
    for (int i = 0; i < gifCursor.getCount(); i++)
        Log.d("gif file uri -> ", gifCursor.getString(columnIndexUri));
}

I want to also avoid the third party modules as they would increase the size of the app. You can suggest if there is any module available for this with low size.

I have Tried checking the existance of flags like ANIM, VP8, in image file and it works well but this explicit method is time consuming.

The major issue in this is webp as same extention would be static or animated. This makes difficult me to identify the animated and static type.

CrackerKSR
  • 1,380
  • 1
  • 11
  • 29
  • 1
    A [semi-related question](https://stackoverflow.com/questions/1412529/how-do-i-programmatically-check-whether-a-gif-image-is-animated) (in python) goes over some approaches for this, which you could take as an inspiration. More information about your setup (backend server, other libraries e.g. ffmpeg available), and _why_ you want to do this, would help in determining a better solution. – Rogue Jun 13 '22 at 13:12
  • ffmpeg has many good features and it is heavy in size. Cannot use that for only type checking. It would increase the app size. I am already using React Native which increases the app size :D. – CrackerKSR Jun 13 '22 at 13:37
  • I tried that magic number checking method and it works but need to extract bytes for each image which causes the little bit delay. – CrackerKSR Jun 13 '22 at 13:39

1 Answers1

1

I think I maybe found a solution... try using ImageDecoder

the documentation says

If the encoded image is an animated GIF or WEBP, decodeDrawable will return an AnimatedImageDrawable.

So maybe checking that the result of ImageDecoder.decodeDrawable(source); is an instance of AnimatedImageDrawable should help you figure out if a file is animated or not

such as:

ImageDecoder.Source source = ImageDecoder.createSource(cr,uri);
Drawable drawable = ImageDecoder.decodeDrawable(source);
  if (drawable instanceof AnimatedImageDrawable) {
      //THE FILE IS ANIMATED
  }else{
      //THE FILE IS STATIC
}

or such as

private boolean isAnimated(ContentResolver cr,Uri uri){
        ImageDecoder.Source source = ImageDecoder.createSource(cr,uri);

        Drawable drawable = ImageDecoder.decodeDrawable(cr,source);
   return drawable instanceof AnimatedImageDrawable;
}

EDIT: for API 28 and before, we should use Movie class

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
  ImageDecoder.Source source = ImageDecoder.createSource(file);
  Drawable drawable = ImageDecoder.decodeDrawable(source);
      return drawable instanceof AnimatedImageDrawable;
} else {
  Movie movie = Movie.decodeStream(input);
  return movie != null;
}

I hope that helps with your problem

Mirco0
  • 306
  • 1
  • 2
  • 8