从图像 URL 获取缩略图 URL。

14

我有一个指向设备外部存储中存储的图像的字符串 URL:

String imageUrl = "/storage/emulated/0/DCIM/100MEDIA/IMAG0823.jpg"

我想查询 MediaStore 以获取此图像的缩略图。这是我现在所做的:

private String getImageThumbnailPath(Context ctx, String imageUrl){

    Cursor cursor = MediaStore.Images.Thumbnails.queryMiniThumbnails(
            ctx.getContentResolver(), Uri.fromFile(new File(imageUrl)),
            MediaStore.Images.Thumbnails.MICRO_KIND,
            null);

    String url = "";
    if( cursor != null && cursor.getCount() > 0 ) {
        cursor.moveToFirst();
        url = cursor.getString( cursor.getColumnIndex( MediaStore.Images.Thumbnails.DATA ) );
        cursor.close();
    }
    return url;
} 

然而,调用此方法并打印其内容时什么也没有显示(光标为空)。

我该如何查询与我的图像URL相关联的缩略图URL的MediaStore

编辑

我还尝试直接从图像URL解析Uri,代码如下:

Cursor cursor = MediaStore.Images.Thumbnails.queryMiniThumbnails(
        ctx.getContentResolver(), Uri.parse(imageUrl),
        MediaStore.Images.Thumbnails.MINI_KIND,
        null);

但结果是一样的。


检查Uri值 Uri.fromFile(new File(imageUrl)) - dieter_h
它是/storage/emulated/0/DCIM/100MEDIA/IMAG0823.jpg @dieter_h - Marcus
3
应该是file:///storage/emulated/0/DCIM/100MEDIA/IMAG0823.jpg。 - dieter_h
抱歉,请忽略上一个评论。System.out.println(Uri.fromFile(new File(imageUrl))); 的输出是 file:///storage/emulated/0/DCIM/100MEDIA/IMAG0823.jpg - Marcus
你找到解决方案了吗? - Dennis Zinkovski
我也想知道你是否找到了解决方案。我无法使用getThumbnail检索缩略图。即使图像ID有效,它也会返回null。 - KMC
4个回答

7
以下代码适用于从图库中选择图片,否则我们无法获得缩略图,必须创建缩略图。 首先要找到MediaStore.Images.Media._ID。
public String[] getRealPathFromURI(Uri contentUri) {
    String[] proj = { MediaStore.Images.Media.DATA,
            MediaStore.Images.Media._ID };
    Cursor cursor = getActivity().getContentResolver().query(contentUri,
            proj, null, null, null);
    int path_index = cursor.getColumnIndexOrThrow(proj[0]);
    int id_index = cursor.getColumnIndexOrThrow(proj[1]);
    cursor.moveToFirst();
    return new String[] { cursor.getString(path_index),
            cursor.getLong(id_index) + "" };
}

从上面的getRealPathFromURI现在我们有了MediaStore.Images.Media._ID,使用这个id来查找缩略图。

public static Bitmap getThumbnail(ContentResolver contentResolver, long id) {
        Cursor cursor = contentResolver.query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                new String[]{MediaStore.Images.Media.DATA}, // Which columns
                // to return
                MediaStore.Images.Media._ID + "=?", // Which rows to return
                new String[]{String.valueOf(id)}, // Selection arguments
                null);// order

        if (cursor != null && cursor.getCount() > 0) {
            cursor.moveToFirst();
            String filePath = cursor.getString(0);
            cursor.close();
            int rotation = 0;
            try {
                ExifInterface exifInterface = new ExifInterface(filePath);
                int exifRotation = exifInterface.getAttributeInt(
                        ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_UNDEFINED);
                if (exifRotation != ExifInterface.ORIENTATION_UNDEFINED) {
                    switch (exifRotation) {
                        case ExifInterface.ORIENTATION_ROTATE_180:
                            rotation = 180;
                            break;
                        case ExifInterface.ORIENTATION_ROTATE_270:
                            rotation = 270;
                            break;
                        case ExifInterface.ORIENTATION_ROTATE_90:
                            rotation = 90;
                            break;
                    }
                }
            } catch (IOException e) {
                Log.e("getThumbnail", e.toString());
            }
            Bitmap bitmap = MediaStore.Images.Thumbnails.getThumbnail(
                    contentResolver, id,
                    MediaStore.Images.Thumbnails.MINI_KIND, null);
            if (rotation != 0) {
                Matrix matrix = new Matrix();
                matrix.setRotate(rotation);
                bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                        bitmap.getHeight(), matrix, true);
            }
            return bitmap;
        } else
            return null;
    }

要使用上述LOC

已更新

String[] imageInfo = getRealPathFromURI(Uri.parse("YOUR_IMAGE_PATH"));
yourImageView.setImageBitmap(getThumbnail(getActivity()
                    .getContentResolver(), Long.parseLong(imageInfo[1])));

Uri.parse("YOUR_IMAGE_PATH") 是内容URI。


第一个方法中的contentUri是什么? - Marcus
getRealPathFromURI 方法中,getActivity().getContentResolver().query(contentUri, proj, null, null, null); 返回了 null。我的 contentUri 是 /storage/emulated/0/DCIM/100MEDIA/IMAG0827.jpg。有什么想法吗? - Marcus
我知道你发表这篇回答已经四年了,但我用MediaStore.Images.Thumbnails.getThumbnail方法遇到了问题。不知何故,它返回null。我检查了我的代码,并且可以看到查询返回正确的游标,我也可以从中提取image_id。 - KMC

2

我相信ThumbnailUtils类可以帮助你实现此功能。

Bitmap thumb = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(imagePath), THUMBSIZE, THUMBSIZE);

它返回一个位图,你应该在使用之前检查它是否为null。有时,损坏的文件会返回空的缩略图。

如果您不支持API 8以下的任何内容,则应该使用此方法。

更新

如果您需要缩略图路径,请使用此方法,

public String getThumbnailPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media._ID };
    String result = null;
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    int column_index = cursor
            .getColumnIndexOrThrow(MediaStore.Images.Media._ID);

    cursor.moveToFirst();
    long imageId = cursor.getLong(column_index);
    cursor.close();

    cursor = MediaStore.Images.Thumbnails.queryMiniThumbnail(
            getContentResolver(), imageId,
            MediaStore.Images.Thumbnails.MINI_KIND,
            null);
    if (cursor != null && cursor.getCount() > 0) {
        cursor.moveToFirst();
        result = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));
        cursor.close();
    }
    return result;
}

我可能在我的问题中表达得不够清楚,但我想要的是位图的url,它存储在MediaStore数据库中。 - Marcus
它对你来说运行得非常完美。我认为你应该先尝试一下。如果它有效,请告诉我。 - Aritra Roy
它被弃用肯定是有原因的,不是吗? - Marcus
@Vishwa,我在哪里提到了ThumbnailUtils被弃用?我说的是managedQuery已经被弃用。 - Marcus
@Marcus 你尝试过这个解决方案吗?对我来说它完美地起作用。我花了时间来帮助你,如果你能尝试一下就太好了。 - Aritra Roy
显示剩余3条评论

0

您可以使用此方法来调整大小并保存原始图像后面的缩略图:

private void resizer(String local_path, int original_image_w, int original_image_h){
    if(local_path.length() > 0){
        int imgW = (int) (original_image_w * 0.10); // Can Change By Device Width
        int imgH = (int) (original_image_h * 0.10); // Can Change By Device height
        Log.d("TAG_RESIZE", "Resizer, W : "+imgW+" , H : "+imgH);
        Log.d("TAG_RESIZE", "Resizer local path : "+(new File(local_path).exists() ? "Exist" : "Not Exist")+" , \n"+local_path);
        String ex = local_path.substring(local_path.lastIndexOf('.')+1, local_path.length());
        // ExceptionHelpers.eLog(G.Logs.Error, "Slider Downloader Image ex : " + ex);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        Bitmap dlBitmap = BitmapFactory.decodeFile(local_path, options);
        Bitmap resized = Bitmap.createScaledBitmap(dlBitmap, imgW, imgH, true);
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(local_path.replace("."+ex, "_thumb."+ex));
            if(ex.toLowerCase().startsWith("jpg") || ex.toLowerCase().startsWith("jpeg")){
                resized.compress(Bitmap.CompressFormat.JPEG,100, fos);
            }else if(ex.toLowerCase().startsWith("png")){
                resized.compress(Bitmap.CompressFormat.PNG,100, fos);
            }

            fos.flush();
            fos.close();

        } catch (Exception e) {
            ExceptionHelpers.catchMessage(e); // My Custom Class To Log Errors, Useful To Save Error Logs And Send To Server
        }
    }
}

它还将捕获内存存储,但比运行时调整大小更快


1
这就是 Bitmap thumb = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(imagePath), THUMBSIZE, THUMBSIZE); 的作用,何必重复造轮子呢?而且,这也不是我要求的。 - Marcus
@Marcus 告诉了你使用它的原因。 - Hossein Kurd

-2

您需要从图库中选择一张图片,否则我们无法生成缩略图。您可以通过以下方式首先启动一个意图来从图库中选择一张图片。

Intent galleryIntent = new Intent(Intent.ACTION_PICK, 
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    galleryIntent.setType("image/*");
                    startActivityForResult(galleryIntent, REQUEST_PICK_FROM_GALLERY);

在你的onActivityResult中执行以下操作

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);

        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case REQUEST_PICK_FROM_GALLERY:
            Bitmap thumbnail = new File(intent.getExtras().get("data"));
                    break;
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接