如何从Bitmap获取Uri对象

28

在某个触发事件中,我要求用户添加图片。所以我提供了两个选项:

  1. 从图库中添加。
  2. 从相机中拍照新建一张图片。

我的目标是维护与这些图片相关的“uri”列表。

如果用户选择了图库,那么我会获取图片的uri(这很简单)。 但是如果他选择了相机,则在拍摄照片后,我会得到该图片的Bitmap对象。

现在,我该如何将该Bitmap对象转换为uri或者说如何获取该位图对象的相对Uri对象?

谢谢。


这可能会有帮助 https://dev59.com/dWsz5IYBdhLWcg3w0rVC - Vishal Vyas
有些代码是非常硬编码的。 我不想硬编码图像文件的名称。 而且图像并不一定保存在DCIM文件夹中。 - Darshan Bidkar
6个回答

58

我在我的项目中遇到了同样的问题,所以我按照这个简单方法(点击这里)从位图中获取Uri。

public Uri getImageUri(Context inContext, Bitmap inImage) {
  ByteArrayOutputStream bytes = new ByteArrayOutputStream();
  inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
  String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
  return Uri.parse(path);
} 

6
Images.Media.insertImage现在已更改为MediaStore.Images.Media.insertImage,另外您需要记住添加此权限:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />。 - Piotr Suchanek
16
在Android 6.0中,它返回了空路径(null path)。 - Anand Savjani
1
两个棉花糖设备,摩托罗拉“返回路径”,但三星“返回空”。有什么帮助吗? - sud007
3
我该如何从存储中删除插入的位图文件? - Sujay U N
这似乎是保存位图。有没有一种方法可以从位图对象中获取URI,而无需保存到文件? - chitgoks
显示剩余2条评论

7
Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);

上面提到的代码使用位图创建缩略图,可能会消耗安卓设备一些额外的空间。

这种方法可以帮助你获取位图的Uri而不会消耗额外的内存。

public Uri bitmapToUriConverter(Bitmap mBitmap) {
   Uri uri = null;
   try {
    final BitmapFactory.Options options = new BitmapFactory.Options();
    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, 100, 100);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    Bitmap newBitmap = Bitmap.createScaledBitmap(mBitmap, 200, 200,
            true);
    File file = new File(getActivity().getFilesDir(), "Image"
            + new Random().nextInt() + ".jpeg");
    FileOutputStream out = getActivity().openFileOutput(file.getName(),
            Context.MODE_WORLD_READABLE);
    newBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
    out.flush();
    out.close();
    //get absolute path
    String realPath = file.getAbsolutePath();
    File f = new File(realPath);
    uri = Uri.fromFile(f);

  } catch (Exception e) {
    Log.e("Your Error Message", e.getMessage());
  }
return uri;
}


public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) >= reqHeight
                && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

更多细节请访问高效加载大型位图


什么是calculateInSampleSize?请添加其方法。 - Anand Savjani
@Anand:这个链接https://dev59.com/53E85IYBdhLWcg3wtV_1 可能会对你有所帮助,如果你找到了正确的解决方案,请告知。 - Hanan
1
我可以确认我关于inSampleSize所说的话。此外,如果图像不是矩形的话,这种方法会扭曲图像。要处理非矩形图像,请使用以下代码:Bitmap newBitmap = Bitmap.createScaledBitmap(mBitmap, mBitmap.getWidth(), mBitmap.getHeight(), true); - lxknvlk
这对我总是返回 null。 - Marc Alexander
@danijax,那么你的解决方案是什么? - Sadegh J
显示剩余3条评论

1
这是对我有用的方法。例如,以位图形式从视频中获取缩略图。然后我们可以将位图对象转换为uri对象。
String videoPath = mVideoUri.getEncodedPath();
System.out.println(videoPath); //prints to console the path of the saved video
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Images.Thumbnails.MINI_KIND);

 Uri thumbUri = getImageUri(this, thumb);

什么是 getImageUri - Bhavin Patel

0

我尝试了我在评论中提到的帖子中的以下代码片段,它对我来说运行良好。

/**
 * Gets the last image id from the media store
 * 
 * @return
 */
private int getLastImageId() {
    final String[] imageColumns = { MediaStore.Images.Media._ID,
            MediaStore.Images.Media.DATA };
    final String imageOrderBy = MediaStore.Images.Media._ID + " DESC";
    Cursor imageCursor = managedQuery(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns,
            null, null, imageOrderBy);
    if (imageCursor.moveToFirst()) {
        int id = imageCursor.getInt(imageCursor
                .getColumnIndex(MediaStore.Images.Media._ID));
        String fullPath = imageCursor.getString(imageCursor
                .getColumnIndex(MediaStore.Images.Media.DATA));
        Log.d(getClass().getSimpleName(), "getLastImageId::id " + id);
        Log.d(getClass().getSimpleName(), "getLastImageId::path "
                + fullPath);
        imageCursor.close();
        return id;
    } else {
        return 0;
    }
}

在logcat中输出:

09-24 16:36:24.500: getLastImageId::id 70
09-24 16:36:24.500: getLastImageId::path /mnt/sdcard/DCIM/Camera/2012-09-24 16.36.20.jpg

此外,我在上面的代码片段中没有看到任何硬编码的名称。 希望这可以帮助到您。


0

尝试使用以下代码。可能对您有帮助:

new AsyncTask<Void, Integer, Void>() {
            protected void onPreExecute() {
            };

            @Override
            protected Void doInBackground(Void... arg0) {
                imageAdapter.images.clear();
                initializeVideoAndImage();
                return null;
            }

            protected void onProgressUpdate(Integer... integers) {
                imageAdapter.notifyDataSetChanged();
            }

            public void initializeVideoAndImage() {
                final String[] columns = { MediaStore.Images.Media.DATA, MediaStore.Images.Thumbnails._ID };
                String orderBy = MediaStore.Images.Media._ID;
                Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, orderBy);

                final String[] videocolumns = { MediaStore.Video.Thumbnails._ID, MediaStore.Video.Media.DATA };
                orderBy = MediaStore.Video.Media._ID;
                Cursor videoCursor = managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, videocolumns, null, null, orderBy);
                int i = 0;
                int image_column_index = 0;

                if (imageCursor != null) {
                    image_column_index = imageCursor.getColumnIndex(MediaStore.Images.Media._ID);
                    int count = imageCursor.getCount();
                    for (i = 0; i < count; i++) {
                        imageCursor.moveToPosition(i);
                        int id = imageCursor.getInt(image_column_index);
                        ImageItem imageItem = new ImageItem();
                        imageItem.id = id;
                        imageAdapter.images.add(imageItem);

                    }
                }

                if (videoCursor != null) {
                    image_column_index = videoCursor.getColumnIndex(MediaStore.Video.Media._ID);
                    int count = videoCursor.getCount();
                    for (i = 0; i < count; i++) {
                        videoCursor.moveToPosition(i);
                        int id = videoCursor.getInt(image_column_index);
                        ImageItem imageItem = new ImageItem();
                        imageItem.id = id;
                        imageAdapter.images.add(imageItem);
                    }
                }
                publishProgress(i);
                if (imageCursor != null) {
                    image_column_index = imageCursor.getColumnIndex(MediaStore.Images.Media._ID);
                    int count = imageCursor.getCount();
                    for (i = 0; i < count; i++) {
                        imageCursor.moveToPosition(i);
                        int id = imageCursor.getInt(image_column_index);
                        int dataColumnIndex = imageCursor.getColumnIndex(MediaStore.Images.Media.DATA);
                        ImageItem imageItem = imageAdapter.images.get(i);
                        Bitmap img = MediaStore.Images.Thumbnails.getThumbnail(getApplicationContext().getContentResolver(), id, MediaStore.Images.Thumbnails.MICRO_KIND, null);
                        int column_index = imageCursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                        imageItem.imagePath = imageCursor.getString(column_index);
                        imageItem.videoPath = "";
                        try {
                            File imageFile = new File(Environment.getExternalStorageDirectory(), "image" + i);
                            imageFile.createNewFile();
                            ByteArrayOutputStream bos = new ByteArrayOutputStream();

                            if (bos != null && img != null) {
                                img.compress(Bitmap.CompressFormat.PNG, 100, bos);
                            }
                            byte[] bitmapData = bos.toByteArray();
                            FileOutputStream fos = new FileOutputStream(imageFile);
                            fos.write(bitmapData);
                            fos.close();
                            imageItem.thumbNailPath = imageFile.getAbsolutePath();
                            try {
                                boolean cancelled = isCancelled();
                                // if async task is not cancelled, update the
                                // progress
                                if (!cancelled) {
                                    publishProgress(i);
                                    SystemClock.sleep(100);

                                }

                            } catch (Exception e) {
                                Log.e("Error", e.toString());
                            }
                            // publishProgress();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        // imageAdapter.images.add(imageItem);
                    }
                }
                imageCursor.close();

                if (videoCursor != null) {
                    image_column_index = videoCursor.getColumnIndex(MediaStore.Video.Media._ID);
                    int count = videoCursor.getCount() + i;
                    for (int j = 0; i < count; i++, j++) {
                        videoCursor.moveToPosition(j);
                        int id = videoCursor.getInt(image_column_index);
                        int column_index = videoCursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
                        ImageItem imageItem = imageAdapter.images.get(i);
                        imageItem.imagePath = videoCursor.getString(column_index);
                        imageItem.videoPath = imageItem.imagePath;
                        System.out.println("External : " + imageItem.videoPath);
                        try {
                            File imageFile = new File(Environment.getExternalStorageDirectory(), "imageV" + i);
                            imageFile.createNewFile();
                            ByteArrayOutputStream bos = new ByteArrayOutputStream();
                            MediaMetadataRetriever mediaVideo = new MediaMetadataRetriever();
                            mediaVideo.setDataSource(imageItem.videoPath);
                            Bitmap videoFiles = mediaVideo.getFrameAtTime();
                            videoFiles = ThumbnailUtils.extractThumbnail(videoFiles, 96, 96);
                            if (bos != null && videoFiles != null) {
                                videoFiles.compress(Bitmap.CompressFormat.JPEG, 100, bos);

                            }
                            byte[] bitmapData = bos.toByteArray();
                            FileOutputStream fos = new FileOutputStream(imageFile);
                            fos.write(bitmapData);
                            fos.close();
                            imageItem.imagePath = imageFile.getAbsolutePath();
                            imageItem.thumbNailPath = imageFile.getAbsolutePath();
                            try {
                                boolean cancelled = isCancelled();
                                // if async task is not cancelled, update the
                                // progress
                                if (!cancelled) {
                                    publishProgress(i);
                                    SystemClock.sleep(100);

                                }

                            } catch (Exception e) {
                                Log.e("Error", e.toString());
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    }
                }
                videoCursor.close();
            }

            protected void onPostExecute(Void result) {
                imageAdapter.notifyDataSetChanged();
            };

        }.execute();

    }

0
注意:如果您使用的是Android 6.0或更高版本,则路径将返回空值。 因此,您必须添加权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
public void onClicked(View view){
        Bitmap bitmap=getBitmapFromView(scrollView,scrollView.getChildAt(0).getHeight(),scrollView.getChildAt(0).getWidth());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG,90,baos);
        String path = MediaStore.Images.Media.insertImage(getContentResolver(),bitmap,"title",null);
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("image/jpeg");
        intent.putExtra(Intent.EXTRA_STREAM,Uri.parse(path));
        startActivity(Intent.createChooser(intent,"Share Screenshot Using"));
    }

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