Android 如何从位图获取 Uri 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12555420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 10:58:03  来源:igfitidea点击:

How to get a Uri object from Bitmap

androidbitmapuri

提问by Darshan Bidkar

On a certain tap event, I ask the user to add an image. So I provide two options:

在某个点击事件中,我要求用户添加图像。所以我提供两个选项:

  1. To add from gallery.
  2. To click a new image from camera.
  1. 从图库中添加。
  2. 单击来自相机的新图像。

My aim is to keep a list of "uri"s related to those images.

我的目标是保留与这些图像相关的“uri”列表。

If the user chooses gallery, then I get the image uri (which is quite simple). But if he chooses camera, then after taking a picture, I am getting the Bitmap object of that picture.

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

Now how do I convert that Bitmap object to uri, or in other words, how can I get the relative Uri object of that bitmap object?

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

Thanks.

谢谢。

回答by Ajay

I have same problem in my project, so i follow the simple method (click here) to get Uri from bitmap.

我的项目中有同样的问题,所以我按照简单的方法(单击此处)从位图中获取 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);
} 

回答by Hanan

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

the line mentioned above create a thumbnail using bitmap, that may consume some extra space in your android device.

上面提到的行使用位图创建缩略图,这可能会占用您的 android 设备中的一些额外空间。

This method may help you to get the Uri from bitmap without consuming some extra memory.

这种方法可以帮助您从位图中获取 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;
}

for more details goto Loading Large Bitmaps Efficiently

有关更多详细信息,请转到有效加载大位图

回答by Ronny Kibet

This is what worked for me. For example getting thumbnail from a video in the form of a bitmap. Then we can convert the bitmap object to uri object.

这对我有用。例如,以位图的形式从视频中获取缩略图。然后我们可以将位图对象转换为 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);

回答by Vishal Vyas

I tried the following code snippet from the post I mentioned in my comment..and it's working fine for me.

我尝试了我在评论中提到帖子中的以下代码片段..它对我来说很好用。

/**
 * 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;
    }
}

OutPut in logcat:

在 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

Also I don't see any harcoded names in the above code snippet. Hope this helps.

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

回答by Jay Thakkar

Try to use the below Code. May be helpful to you:

尝试使用下面的代码。可能对你有帮助:

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();

    }

回答by Omi

Note : if you are using android 6.0 or greater version path will give null value. so you have to add permission <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

注意:如果您使用的是 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"));
    }

回答by M Moersalin

if you get image from camera there is no way to get Uri from a bitmap, so you should save your bitmap first.

如果您从相机获取图像,则无法从位图获取 Uri,因此您应该先保存您的位图。

launch camera intent

启动相机意图

startActivityForResult(Intent(MediaStore.ACTION_IMAGE_CAPTURE), 8)

then, override

然后,覆盖

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

    if (resultCode == Activity.RESULT_OK && requestCode == 8) {
        val bitmap = data?.extras?.get("data") as Bitmap

        val uri = readWriteImage(bitmap)
    }
}

also create method to store bitmap and then return the Uri

还创建方法来存储位图,然后返回 Uri

fun readWriteImage(bitmap: Bitmap): Uri {
    // store in DCIM/Camera directory
    val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
    val cameraDir = File(dir, "Camera/")

    val file = if (cameraDir.exists()) {
        File(cameraDir, "LK_${System.currentTimeMillis()}.png")
    } else {
        cameraDir.mkdir()
        File(cameraDir, "LK_${System.currentTimeMillis()}.png")
    }

    val fos = FileOutputStream(file)
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)
    fos.flush()
    fos.close()

    Uri.fromFile(file)
}

PS: dont forget to Add Permission and handle runtime permission (API >= 23)

PS:不要忘记添加权限和处理运行时权限(API >= 23)