Android:给定原始图像的Uri,获取SD卡上图像的缩略图

Posted

技术标签:

【中文标题】Android:给定原始图像的Uri,获取SD卡上图像的缩略图【英文标题】:Android: Get thumbnail of image on SD card, given Uri of original image 【发布时间】:2011-06-22 10:00:19 【问题描述】:

所以我有一个用户从他的 SD 卡中选择的图像的 Uri。而且我想显示该图像的缩略图,因为显然,图像可能很大并且占据整个屏幕。有人知道怎么做吗?

【问题讨论】:

【参考方案1】:

此代码将完成这项工作:

Bitmap getPreview(URI uri) 
    File image = new File(uri);

    BitmapFactory.Options bounds = new BitmapFactory.Options();
    bounds.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(image.getPath(), bounds);
    if ((bounds.outWidth == -1) || (bounds.outHeight == -1))
        return null;

    int originalSize = (bounds.outHeight > bounds.outWidth) ? bounds.outHeight
            : bounds.outWidth;

    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inSampleSize = originalSize / THUMBNAIL_SIZE;
    return BitmapFactory.decodeFile(image.getPath(), opts);     

您可能需要计算最接近 2 的幂以用于 inSampleSize,因为 it's said 更快。

【讨论】:

什么是缩略图大小 构造函数 File(Uri) 未定义 inSampleSize 的 2 的幂不是更快,但算法需要。请注意,图像可能比 THUMBNAIL_SIZE 大得多,因为例如,如果 inSampleSize = originalSize / THUMBNAIL_SIZE 为 7,inSampleSize 将向下舍入为 4,从而为您提供 originalSize/4 的大小,这是您期望每个维度的大小的 1.75 倍,即像素的3倍。对于较大的样本量,这种影响会迅速增加【参考方案2】:

我相信此代码是从 SD 卡上的文件生成缩略图的最快方法:

 public static Bitmap decodeFile(String file, int size) 
    //Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(file, o);

    //Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = (int)Maths.pow(2, (double)(scale-1));
    while (true) 
        if (width_tmp / 2 < size || height_tmp / 2 < size) 
            break;
        
        width_tmp /= 2;
        height_tmp /= 2;
        scale++;
    

    //Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    return BitmapFactory.decodeFile(file, o2);

【讨论】:

Destil 你的规模被低估了,它是 2(scale-1)。在 Java 中:(int)Maths.pow(2, (double)(scale-1)) 我认为您在编辑中破坏了此代码,它在自己的作业中使用了比例。也没有像“数学”这样的包。【参考方案3】:

您可以使用 java 的 ThumnailUtil 类简单地创建缩略图视频和图像

Bitmap resized = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(file.getPath()), width, height);


 public static Bitmap createVideoThumbnail (String filePath, int kind)

在 API 级别 8 中添加 为视频创建视频缩略图。如果视频损坏或格式不受支持,则可能返回 null。

参数 filePath 视频文件的路径 kind 可以是 MINI_KIND 或 MICRO_KIND

For more Source code of Thumbnail Util class

Developer.android.com

【讨论】:

【参考方案4】:

尝试了几次,我无法从 SD 中获取图像的缩略图路径。 在为 gridview(或您需要的地方)在适配器中创建图像视图之前,我已经解决了获取 android 图像位图的问题。所以我调用方法imageView.setImageBitmap(someMethod(Context context, imageID))

Bitmap someMethod(Context context, long imageId)

    Bitmap bitmap =   Media.Images.Thumbnails.getThumbnail(context.getAplicationContext.getContentResolver(), imageid, MediaStore.Images.Thumbnails.MINI_KIND, null);
    return bitmap;

您可以使用本指南从 SD 获取图像 ID (Get list of photo galleries on Android)

【讨论】:

【参考方案5】:

如果您喜欢总部缩略图,请使用 [RapidDecoder][1] 库。很简单,如下:

import rapid.decoder.BitmapDecoder;
...
Bitmap bitmap = BitmapDecoder.from(getResources(), R.drawable.image)
                             .scale(width, height)
                             .useBuiltInDecoder(true)
                             .decode();

如果您想缩小小于 50% 并获得 HQ 结果,请不要忘记使用内置解码器。 我在 API 级别 8 中对其进行了测试 :)

【讨论】:

【参考方案6】:

此包将允许您访问图像 URI 以接收图像大小、大位图数据、将图像采样到任何较小的大小以节省内存并最大限度地提高性能。

它使用 InputStream 和 BitmapFactory:

public int[] getImageSize(Uri uri)
    try 
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        InputStream input = this.getContentResolver().openInputStream(uri);
        BitmapFactory.decodeStream(input, null, options); input.close();
        return new int[]options.outWidth, options.outHeight;
    
    catch (Exception e)
    return new int[]0,0;

public Bitmap BitmapImage(Uri uri)return BitmapImage(uri,-1,-1);
public Bitmap BitmapImage(Uri uri, int maxSize)return BitmapImage(uri,maxSize,maxSize);
public Bitmap BitmapImage(Uri uri, int Wmax, int Hmax)
    try    
        InputStream input = this.getContentResolver().openInputStream(uri);
        double ratio=1;
        if ((Wmax>-1)&&(Hmax>-1))
            int[] wh=getImageSize(uri); double w=wh[0], h=wh[1];
            if (w/Wmax>1)ratio=Wmax/w; if (h*ratio>Hmax)ratio=Hmax/h;
            else if (h/Hmax>1)ratio=Hmax/h;
        
        BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
        bitmapOptions.inSampleSize = (int)Math.ceil(1/ratio);
        bitmapOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;
        Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
        input.close();
        return bitmap;
    
    catch (Exception e)
    return null;

针对不同用例的四种功能:

/*
    getImageSize(Uri uri): return int[] width, height
    BitmapImage(Uri uri): return Bitmap in full size
    BitmapImage(Uri uri, int maxSize): return sampled Bitmap which is limited in square size
    BitmapImage(Uri uri, int Wmax, int Hmax): return sampled Bitmap which is limited width and height
*/

【讨论】:

以上是关于Android:给定原始图像的Uri,获取SD卡上图像的缩略图的主要内容,如果未能解决你的问题,请参考以下文章

Android:如何获取匹配缩略图 URI 的文件路径?

如何在 Android 中获取 SD 卡上文件夹的大小?

获取存储在 sd 卡 + android 中的图像的缩略图 Uri/路径

以编程方式从 Android 的内置图库应用程序中获取/选择图像

在 Android sdk 2.2 中在 SD 卡上安装应用程序

从URI获取真实路径,Android KitKat新的存储访问框架[重复]