【问题标题】:Check if a file is an image or a video检查文件是图像还是视频
【发布时间】:2013-07-11 04:26:50
【问题描述】:

有没有办法检查我作为 URI 加载的文件是 android 中的图像还是视频?我正在尝试将图像和视频动态加载到列表/详细视图的片段中,并且需要将它们区分开来。

【问题讨论】:

    标签: android


    【解决方案1】:

    我猜最简单的方法是检查扩展名

    if ( file.toString().endsWith(".jpg") {
    //photo
    } else if (file.toString().endsWith(".3gp")) {
    //video
    }
    

    【讨论】:

    • 我认为这不应该是公认的答案。有很长的扩展列表可能是图像或视频,并且该列表可能会随着时间的推移而增长,因此手动维护很痛苦。我现在就自己写。
    • 对于“toString()”之后缺少的toLowerCase() 什么都不说;-)
    • 这是检测文件格式的非常糟糕的方法。除了 alfongj 的评论之外,还有一个扩展名不必匹配的问题。
    • 更新:请注意,@alfongj 的回答是正确的,我的回答更像是一种黑客/快速修复方式,可能适用于某些情况..
    • 这不是正确答案,因为文件扩展名可能与文件 mime 类型不同!
    【解决方案2】:

    如果您从内容解析器获取 Uri,则可以使用 getType(Uri); 获取 mime 类型;

    ContentResolver cR = context.getContentResolver();
    String type = cR.getType(uri); 
    

    应该返回类似于“image/jpeg”的东西,你可以检查你的显示逻辑。

    【讨论】:

    • 为我返回 null,URI 是从 XML 构建的,代码为 `Uri uri = Uri.parse(packageLocation+DummyContent.INFO_MAP.get(getArguments().getString(ARG_ITEM_ID)) .get(0)); ` 其中 info_map 是具有 (String, ArrayList) 配对的映射,其中 get(0) 给出文件名,而 get(1) 现在从 xml 中获取视频类型的参数。我希望摆脱那里对数组列表的需求以提高性能。如果文件是 vid.p4,get(0) 会给你类似 vid 的东西。
    • getType(Uri) 函数如果无法确定给定 uri 的 mime 类型,则返回 null。我的猜测是您的文件 mime 不是公认的类型之一。
    • 但它们是 jpg 和 mp4。这很奇怪
    【解决方案3】:

    我会检查 mimeType,然后检查它是否对应于图像或视频。

    检查文件路径是否为图像的完整示例如下:

    public static boolean isImageFile(String path) {
        String mimeType = URLConnection.guessContentTypeFromName(path);
        return mimeType != null && mimeType.startsWith("image");
    }
    

    对于视频:

    public static boolean isVideoFile(String path) {
        String mimeType = URLConnection.guessContentTypeFromName(path);
        return mimeType != null && mimeType.startsWith("video");
    }
    

    【讨论】:

    • 好答案。想提一下,java String 对象有一个 .startsWith 方法,它比 indexOf == 0 更具可读性。
    • 这不起作用,如果给定的路径不包含图像扩展名。例如。 Android 相机应用程序可能会返回类似“content://com.android.providers.media.documents/document/im‌​age%3A130”的路径,isImageFile() 将返回 false。这似乎有效:stackoverflow.com/a/31691791/1665966
    • 错误答案,因为该代码无法处理视频 mime 类型。 URLConnection.guessContentTypeFromName(...) 方法的来源在这里:github.com/AndroidSDKSources/… 如您所见,仅支持最小的一组 mime 类型,并且不包含视频 mime 类型。 Oracle Java 13和OpenJDK的源代码相同。
    【解决方案4】:

    通过ContentResolver(如jsrssoftwareanswer)检查类型似乎是最合适的。不过,在某些情况下,这可能会返回 null

    在这种情况下,我最终尝试将流解码为位图以确认它在图像中(但仅解码边界,因此速度非常快且不占用太多内存)。

    我的图像测试器辅助函数如下所示:

    public static boolean checkIsImage(Context context, Uri uri) {
        ContentResolver contentResolver = context.getContentResolver();
        String type = contentResolver.getType(uri);
        if (type != null) {
            return  type.startsWith("image/");
        } else {
            // try to decode as image (bounds only)
            InputStream inputStream = null;
            try {
                inputStream = contentResolver.openInputStream(uri);
                if (inputStream != null) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inJustDecodeBounds = true;
                    BitmapFactory.decodeStream(inputStream, null, options);
                    return options.outWidth > 0 && options.outHeight > 0;
                }
            } catch (IOException e) {
                // ignore
            } finally {
                FileUtils.closeQuietly(inputStream);
            }
        }
        // default outcome if image not confirmed
        return false;
    }
    

    对于视频,可以采用类似的方法。我不需要它,但我相信MediaMetadataRetriever 可用于验证流是否包含有效视频,以防type 检查失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-13
      • 2020-10-26
      • 2015-11-23
      • 1970-01-01
      • 2019-02-09
      • 1970-01-01
      • 2017-07-13
      • 2011-03-05
      相关资源
      最近更新 更多