Android相机意图:如何获取全尺寸照片?

发布于 2024-11-17 00:42:47 字数 777 浏览 2 评论 0原文

我正在使用意图启动相机:

Intent cameraIntent = new Intent(
    android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
getParent().startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);

并使用:

Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
photoImage.setImageBitmap(thumbnail);
photoImage.setVisibility(View.VISIBLE);

但它只是一个缩略图,如何获取完整的位图?我知道我可以使用自己的 Activity 并使用:

Camera.PictureCallback()

但是有没有办法使用 Intent 来做到这一点?

谢谢!

编辑:

我也尝试过:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    Uri uri = data.getData();
    imageView.setImageURI(uri);
}

它适用于从图库中选择的照片,但对于相机意图,data.getData() 返回 null。

I am using intent to launch camera:

Intent cameraIntent = new Intent(
    android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
getParent().startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);

and using:

Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
photoImage.setImageBitmap(thumbnail);
photoImage.setVisibility(View.VISIBLE);

But it is only a thumbnail, how do I get the full bitmap? I know I can use my own Activity and use:

Camera.PictureCallback()

But is there anyway to do it using Intent?

Thanks!

edit:

I also tried:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    Uri uri = data.getData();
    imageView.setImageURI(uri);
}

It works for photo selected from gallery, but for camera intent, data.getData() returns null.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

末が日狂欢 2024-11-24 00:42:47

要获得全尺寸的相机图像,您应该将相机指向临时文件中保存图片,例如:

    private URI mImageUri;

    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    File photo;
    try
    {
        // place where to store camera taken picture
        photo = this.createTemporaryFile("picture", ".jpg");
        photo.delete();
    }
    catch(Exception e)
    {
        Log.v(TAG, "Can't create file to take picture!");
        Toast.makeText(activity, "Please check SD card! Image shot is impossible!", 10000);
        return false;
    }
    mImageUri = Uri.fromFile(photo);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
    //start camera intent
    activity.startActivityForResult(this, intent, MenuShootImage);

private File createTemporaryFile(String part, String ext) throws Exception
{
    File tempDir= Environment.getExternalStorageDirectory();
    tempDir=new File(tempDir.getAbsolutePath()+"/.temp/");
    if(!tempDir.exists())
    {
        tempDir.mkdirs();
    }
    return File.createTempFile(part, ext, tempDir);
}

然后在图像捕获意图完成工作后 - 只需使用以下代码从 imageUri 抓取您的图片:

public void grabImage(ImageView imageView)
{
    this.getContentResolver().notifyChange(mImageUri, null);
    ContentResolver cr = this.getContentResolver();
    Bitmap bitmap;
    try
    {
        bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageUri);
        imageView.setImageBitmap(bitmap);
    }
    catch (Exception e)
    {
        Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
        Log.d(TAG, "Failed to load", e);
    }
}


//called after camera intent finished
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
    //MenuShootImage is user defined menu option to shoot image
    if(requestCode==MenuShootImage && resultCode==RESULT_OK) 
    {
       ImageView imageView;
       //... some code to inflate/create/find appropriate ImageView to place grabbed image
       this.grabImage(imageView);
    }
    super.onActivityResult(requestCode, resultCode, intent);
}

PS< /strong> 需要针对 Android M 中应用的新安全限制修改代码 - 文件提供程序mImageUri 必须与 FileProvider 一起打包

To get full sized camera image you should point camera to save picture in temporary file, like:

    private URI mImageUri;

    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    File photo;
    try
    {
        // place where to store camera taken picture
        photo = this.createTemporaryFile("picture", ".jpg");
        photo.delete();
    }
    catch(Exception e)
    {
        Log.v(TAG, "Can't create file to take picture!");
        Toast.makeText(activity, "Please check SD card! Image shot is impossible!", 10000);
        return false;
    }
    mImageUri = Uri.fromFile(photo);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
    //start camera intent
    activity.startActivityForResult(this, intent, MenuShootImage);

private File createTemporaryFile(String part, String ext) throws Exception
{
    File tempDir= Environment.getExternalStorageDirectory();
    tempDir=new File(tempDir.getAbsolutePath()+"/.temp/");
    if(!tempDir.exists())
    {
        tempDir.mkdirs();
    }
    return File.createTempFile(part, ext, tempDir);
}

Then after image capture intent finished to work - just grab your picture from imageUri using following code:

public void grabImage(ImageView imageView)
{
    this.getContentResolver().notifyChange(mImageUri, null);
    ContentResolver cr = this.getContentResolver();
    Bitmap bitmap;
    try
    {
        bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageUri);
        imageView.setImageBitmap(bitmap);
    }
    catch (Exception e)
    {
        Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
        Log.d(TAG, "Failed to load", e);
    }
}


//called after camera intent finished
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
    //MenuShootImage is user defined menu option to shoot image
    if(requestCode==MenuShootImage && resultCode==RESULT_OK) 
    {
       ImageView imageView;
       //... some code to inflate/create/find appropriate ImageView to place grabbed image
       this.grabImage(imageView);
    }
    super.onActivityResult(requestCode, resultCode, intent);
}

P.S. Code need to be revised with respect to new security restriction applied in Android M - FileProvider: mImageUri has to be packed with FileProvider

羁绊已千年 2024-11-24 00:42:47

打开相机并将图像保存到某个特定目录

private String pictureImagePath = "";
private void openBackCamera() {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = timeStamp + ".jpg";
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    pictureImagePath = storageDir.getAbsolutePath() + "/" + imageFileName;
    File file = new File(pictureImagePath);
    Uri outputFileUri = Uri.fromFile(file);
    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);               
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
    startActivityForResult(cameraIntent, 1);
}

处理图像

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 1) {
    File imgFile = new  File(pictureImagePath);
        if(imgFile.exists()){        
       Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
       ImageView myImage = (ImageView) findViewById(R.id.imageviewTest);
       myImage.setImageBitmap(myBitmap);

        }
    }

}

Open Camera and save image into some specific directory

private String pictureImagePath = "";
private void openBackCamera() {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = timeStamp + ".jpg";
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    pictureImagePath = storageDir.getAbsolutePath() + "/" + imageFileName;
    File file = new File(pictureImagePath);
    Uri outputFileUri = Uri.fromFile(file);
    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);               
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
    startActivityForResult(cameraIntent, 1);
}

Handle Image

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 1) {
    File imgFile = new  File(pictureImagePath);
        if(imgFile.exists()){        
       Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
       ImageView myImage = (ImageView) findViewById(R.id.imageviewTest);
       myImage.setImageBitmap(myBitmap);

        }
    }

}
秋意浓 2024-11-24 00:42:47

尽管这是一个老问题并且有一个公认的答案,
我想分享我的解决方案。
在这种情况下,您不必创建临时文件。
此外,我们创建一个选择器,为用户提供以下两种服务:用相机拍照或从图库中选择现有的一张照片。

    Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    Intent chooser = new Intent(Intent.ACTION_CHOOSER);
    chooser.putExtra(Intent.EXTRA_INTENT, galleryIntent);
    chooser.putExtra(Intent.EXTRA_TITLE, getString(R.string.chooseaction));
    Intent[] intentArray = {cameraIntent};
    chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
    startActivityForResult(chooser, RESULT_LOAD_IMAGE);

在这里我们检索结果:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // todo use appropriate resultCode in your case
    if (requestCode == RESULT_LOAD_IMAGE && resultCode == FragmentActivity.RESULT_OK) {
        if (data.getData() != null) {
            // this case will occur in case of picking image from the Gallery,
            // but not when taking picture with a camera
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), data.getData());

                // do whatever you want with the Bitmap ....           

            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            // this case will occur when taking a picture with a camera
            Bitmap bitmap = null;
            Cursor cursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    new String[]{MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_ADDED,
                            MediaStore.Images.ImageColumns.ORIENTATION}, MediaStore.Images.Media.DATE_ADDED,
                    null, "date_added DESC");
            if (cursor != null && cursor.moveToFirst()) {
                Uri uri = Uri.parse(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)));
                String photoPath = uri.toString();
                cursor.close();
                if (photoPath != null) {
                    bitmap = BitmapFactory.decodeFile(photoPath);
                }
            }

            if (bitmap == null) {
                // for safety reasons you can
                // use thumbnail if not retrieved full sized image
                bitmap = (Bitmap) data.getExtras().get("data");
            }
            // do whatever you want with the Bitmap ....
        }

        super.onActivityResult(requestCode, resultCode, data);
    }
}

Even though this is an old question and it has an accepted answer,
I would like to share my solution.
In this case you don't have to create a temporary file.
Additionally we creating a chooser which offers to user both: take a picture with the camera or pick an existing one from a gallery.

    Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    Intent chooser = new Intent(Intent.ACTION_CHOOSER);
    chooser.putExtra(Intent.EXTRA_INTENT, galleryIntent);
    chooser.putExtra(Intent.EXTRA_TITLE, getString(R.string.chooseaction));
    Intent[] intentArray = {cameraIntent};
    chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
    startActivityForResult(chooser, RESULT_LOAD_IMAGE);

and here we retrieving results:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // todo use appropriate resultCode in your case
    if (requestCode == RESULT_LOAD_IMAGE && resultCode == FragmentActivity.RESULT_OK) {
        if (data.getData() != null) {
            // this case will occur in case of picking image from the Gallery,
            // but not when taking picture with a camera
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), data.getData());

                // do whatever you want with the Bitmap ....           

            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            // this case will occur when taking a picture with a camera
            Bitmap bitmap = null;
            Cursor cursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    new String[]{MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_ADDED,
                            MediaStore.Images.ImageColumns.ORIENTATION}, MediaStore.Images.Media.DATE_ADDED,
                    null, "date_added DESC");
            if (cursor != null && cursor.moveToFirst()) {
                Uri uri = Uri.parse(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)));
                String photoPath = uri.toString();
                cursor.close();
                if (photoPath != null) {
                    bitmap = BitmapFactory.decodeFile(photoPath);
                }
            }

            if (bitmap == null) {
                // for safety reasons you can
                // use thumbnail if not retrieved full sized image
                bitmap = (Bitmap) data.getExtras().get("data");
            }
            // do whatever you want with the Bitmap ....
        }

        super.onActivityResult(requestCode, resultCode, data);
    }
}
梦途 2024-11-24 00:42:47

我还使用了 Vicky 的答案,但我必须将 uri 保存到一个包中,以避免在方向更改时丢失它。因此,如果您在倾斜设备后没有从意图中得到结果,可能是因为您的 uri 无法承受方向变化。

static final int CAMERA_CAPTURE_REQUEST = 1;
static final String ARG_CURRENT_PIC_URI = "CURRENT_PIC_URI";


String pictureImagePath = folderName + "/" + imageFileName;
File file = new File(Environment.getExternalStorageDirectory(), pictureImagePath);
Uri outputFileUri = Uri.fromFile(file);

mCurrentPicUri = outputFileUri.getPath();

Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, CAMERA_CAPTURE_REQUEST);

活动结果代码:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {

  if (requestCode == CAMERA_CAPTURE_REQUEST && resultCode == Activity.RESULT_OK) 
  {
    File imgFile = new  File(mCurrentPicUri);
    // do something with your image
    // delete uri
    mCurrentPicUri = "";
  }
}

将 uri 保存到包中:

@Override
public void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  // save uri to bundle
  outState.putString(ARG_CURRENT_PIC_URI, mCurrentPicUri);
}

在创建期间从保存的包中检索它:

if (bundle.containsKey(ARG_CURRENT_PIC_URI))
  mCurrentPicUri = bundle.getString(ARG_CURRENT_PIC_URI);

I also used the answer from Vicky but I had to save the uri to a bundle to avoid loss of it on orientation change. So if you don't get a result from your intent after tilting the device it might be because your uri did not survive the orientation change.

static final int CAMERA_CAPTURE_REQUEST = 1;
static final String ARG_CURRENT_PIC_URI = "CURRENT_PIC_URI";


String pictureImagePath = folderName + "/" + imageFileName;
File file = new File(Environment.getExternalStorageDirectory(), pictureImagePath);
Uri outputFileUri = Uri.fromFile(file);

mCurrentPicUri = outputFileUri.getPath();

Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, CAMERA_CAPTURE_REQUEST);

Activity Result code:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {

  if (requestCode == CAMERA_CAPTURE_REQUEST && resultCode == Activity.RESULT_OK) 
  {
    File imgFile = new  File(mCurrentPicUri);
    // do something with your image
    // delete uri
    mCurrentPicUri = "";
  }
}

save the uri to the bundle:

@Override
public void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  // save uri to bundle
  outState.putString(ARG_CURRENT_PIC_URI, mCurrentPicUri);
}

retrieve it from your saved bundle during on create:

if (bundle.containsKey(ARG_CURRENT_PIC_URI))
  mCurrentPicUri = bundle.getString(ARG_CURRENT_PIC_URI);
胡渣熟男 2024-11-24 00:42:47

不要使用 onActivityResult 的数据。我花了很多时间来测试不同的解决方案。相机保存图片(即使您没有在 AndroidManifest 中设置相机和读卡权限),但随后 onActivityResult 返回 data == nullMediaStore 返回错误的路径。在这些解决方案中,您只需获取最后一个画廊图像,而不是您的照片。

private Uri photoUri;

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    ...
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == CAMERA_RESULT) {
        if (resultCode == RESULT_OK) {
            if (photoUri != null) {
                image.setImageURI(photoUri);
            }
        }
    }
}

private void showCamera() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (intent.resolveActivity(getContext().getPackageManager()) != null) {
        File file = null;
        try {
            file = createImageFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        photoUri = null;
        if (file != null) {
            photoUri = Uri.fromFile(file);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
            startActivityForResult(intent, CAMERA_REQUEST);
        }
    }
}

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File storageDir = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    // File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    return File.createTempFile(timeStamp, ".jpg", storageDir);
}

Don't use onActivityResult's data. It took me many hours to test different solutions. A camera saves a picture (even if you don't set permissions for camera and card reading in AndroidManifest), but then onActivityResult returns data == null and MediaStore returns wrong path. In these solutions you simply get last gallery image, not your photo.

private Uri photoUri;

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    ...
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == CAMERA_RESULT) {
        if (resultCode == RESULT_OK) {
            if (photoUri != null) {
                image.setImageURI(photoUri);
            }
        }
    }
}

private void showCamera() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (intent.resolveActivity(getContext().getPackageManager()) != null) {
        File file = null;
        try {
            file = createImageFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        photoUri = null;
        if (file != null) {
            photoUri = Uri.fromFile(file);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
            startActivityForResult(intent, CAMERA_REQUEST);
        }
    }
}

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File storageDir = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    // File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    return File.createTempFile(timeStamp, ".jpg", storageDir);
}
美人迟暮 2024-11-24 00:42:47

好的,是时候还钱了。

因此,您在清单中拥有权限:

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-feature android:name="android.hardware.camera" android:required="true" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

并且您还拥有提供程序元数据:

 <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"></meta-data>
    </provider>

一个遗漏的细节是(android:authorities applicationId) - 您需要将其添加到您自己的应用程序包名称中。

因此,正如我们在 manifest 中提到的,您在 res 文件夹下有 xml 文件,并在其下创建了 file_paths

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path
        name="my_images"
        path="Pictures" />
</paths>

我们已经完成了复制粘贴第 1 部分。现在,在上面的活动中 onCreate(savedInstanceState: Bundle?) 定义了这些美丽的内容。

    val REQUEST_IMAGE_CAPTURE = 1
    lateinit var currentPhotoPath: String
    var cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

您可能想像往常一样查看原始资源,但缺少详细信息:<一个href="https://developer.android.com/training/camera/photobasics" rel="nofollow noreferrer">链接

另一个缺失的细节是 packageName + ".fileprovider",请注意,如果您已经有方法,则需要提供自己的包名称。

// org android developers
    private fun dispatchTakePictureIntent() {
        Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
            // Ensure that there's a camera activity to handle the intent
            takePictureIntent.resolveActivity(packageManager)?.also {
                // Create the File where the photo should go
                val photoFile: File? = try {
                    createImageFile()
                } catch (ex: IOException) {
                    // Error occurred while creating the File
                    ex.message
                    null
                }
                // Continue only if the File was successfully created
                photoFile?.also {
                    val photoURI: Uri = FileProvider.getUriForFile(
                        this,
                        packageName + ".fileprovider",
                        it
                    )
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
                    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
                }
            }
        }
    }

createImageFile 函数

 // org android developers
    @Throws(IOException::class)
    private fun createImageFile(): File {
        // Create an image file name
        val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        val storageDir: File = this!!.getExternalFilesDir(Environment.DIRECTORY_PICTURES)!!
        return File.createTempFile(
            "JPEG_${timeStamp}_", /* prefix */
            ".jpg", /* suffix */
            storageDir /* directory */
        ).apply {
            // Save a file: path for use with ACTION_VIEW intents
            currentPhotoPath = absolutePath
        }

    }

测试

使用 onClick 事件调用您的 dispatchTakePictureIntent() 方法,确保权限被允许

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
  if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_IMAGE_CAPTURE) {
var  mBitmap_org = MediaStore.Images.Media.getBitmap(
                this.getContentResolver(),
                //Uri.parse(currentPhotoPath)
                Uri.fromFile(File(currentPhotoPath))
            );
        //mImg_display?.setImageBitmap(mBitmap_org)
}
    }

不要检查数据,我们将通过 imagePath 获取它。如果您正在检查Uri.parse(currentPhotoPath),请确保它是Uri.fromFile(File(currentPhotoPath))

现在您有了位图,有时间花其他时间/天如何调整解码大小,保存。

还有一种保存令牌图像的方法,也许你可以帮我看看我应该把它放在哪里,如果我需要将令牌图像保存在图库上

  // org android developers
    private fun galleryAddPic() {
        Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).also { mediaScanIntent ->
            val f = File(currentPhotoPath)
            mediaScanIntent.data = Uri.fromFile(f)
            sendBroadcast(mediaScanIntent)
        }
    }

Ok time to pay back.

So you have your permissions in the manifest:

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-feature android:name="android.hardware.camera" android:required="true" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

And you also have your provider metadata:

 <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"></meta-data>
    </provider>

One missed detail is (android:authorities applicationId) - you need to add this to your own app package name.

So you have xml file under res folder as we mentioned on manifest and under it u have created file_paths with:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path
        name="my_images"
        path="Pictures" />
</paths>

We are done with copy paste part 1. Now on our activity above onCreate(savedInstanceState: Bundle?) define these beauties

    val REQUEST_IMAGE_CAPTURE = 1
    lateinit var currentPhotoPath: String
    var cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

You might like to have a look at original resource but missing details as usual Android Developers : link

An other missing detail is packageName + ".fileprovider", be careful u need to give your own package name if u already have method.

// org android developers
    private fun dispatchTakePictureIntent() {
        Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
            // Ensure that there's a camera activity to handle the intent
            takePictureIntent.resolveActivity(packageManager)?.also {
                // Create the File where the photo should go
                val photoFile: File? = try {
                    createImageFile()
                } catch (ex: IOException) {
                    // Error occurred while creating the File
                    ex.message
                    null
                }
                // Continue only if the File was successfully created
                photoFile?.also {
                    val photoURI: Uri = FileProvider.getUriForFile(
                        this,
                        packageName + ".fileprovider",
                        it
                    )
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
                    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
                }
            }
        }
    }

createImageFile function

 // org android developers
    @Throws(IOException::class)
    private fun createImageFile(): File {
        // Create an image file name
        val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        val storageDir: File = this!!.getExternalFilesDir(Environment.DIRECTORY_PICTURES)!!
        return File.createTempFile(
            "JPEG_${timeStamp}_", /* prefix */
            ".jpg", /* suffix */
            storageDir /* directory */
        ).apply {
            // Save a file: path for use with ACTION_VIEW intents
            currentPhotoPath = absolutePath
        }

    }

Testing.

Call your dispatchTakePictureIntent() method with onClick event, make sure permissions are permitted

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
  if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_IMAGE_CAPTURE) {
var  mBitmap_org = MediaStore.Images.Media.getBitmap(
                this.getContentResolver(),
                //Uri.parse(currentPhotoPath)
                Uri.fromFile(File(currentPhotoPath))
            );
        //mImg_display?.setImageBitmap(mBitmap_org)
}
    }

Don't check data we will get it through imagePath. If u are checking Uri.parse(currentPhotoPath) make sure it's Uri.fromFile(File(currentPhotoPath))

Now you have your bitmap, time to spend other hours/days how to resize decode, save.

There is also a method to save token image, maybe you could help me to see where should I put it, if I need token image to be save on gallery

  // org android developers
    private fun galleryAddPic() {
        Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).also { mediaScanIntent ->
            val f = File(currentPhotoPath)
            mediaScanIntent.data = Uri.fromFile(f)
            sendBroadcast(mediaScanIntent)
        }
    }
蓝海似她心 2024-11-24 00:42:47

API 级别 29

我尝试了接受的答案,但是在接受的答案中使用了 Environment.getExternalStorageDirectory() ,并且在后续答案在 API 级别 29 中已弃用。第三个答案中使用的 MediaStore.Images.Media.DATA 在 API 级别中也已弃用29. 以下代码(Kotlin 中)将完整图像存储在 MediaStore 中,如此 stackoverflow 答案 到另一个问题,并且不依赖于 FileProvider

    var imageUri: Uri? = null

    fun takePhoto(view: View?) {
        val values = ContentValues()
        values.put(MediaStore.MediaColumns.DISPLAY_NAME, "myimage.jpg")
        values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
        values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
        imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)

        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
        startActivityForResult(intent, TAKE_PHOTO_REQUEST)
    }

API Level 29

I tried the accepted answer, but both Environment.getExternalStorageDirectory() used in the accepted answer and Environment.getExternalStoragePublicDirectory() used in a subsequent answer are deprecated in API level 29. So is the MediaStore.Images.Media.DATA used in the third answer deprecated in API level 29. The following code (in Kotlin) stores the full image in MediaStore as shown in this stackoverflow answer to a different question and doesn't rely on the FileProvider:

    var imageUri: Uri? = null

    fun takePhoto(view: View?) {
        val values = ContentValues()
        values.put(MediaStore.MediaColumns.DISPLAY_NAME, "myimage.jpg")
        values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
        values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
        imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)

        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
        startActivityForResult(intent, TAKE_PHOTO_REQUEST)
    }
面如桃花 2024-11-24 00:42:47

要从相机捕获最大图片尺寸,我希望这些简单的步骤非常有用。

 public static Camera mCamera;

Camera.Parameters parameters = mCamera.getParameters();
  parameters.getSupportedPictureSizes();
List<Camera.Size> supportedSizes = parameters.getSupportedPictureSizes();
  mSizePicture1 = supportedSizes.get(0);
  int cameraSize = supportedSizes.size();
  mSizePicture2 = supportedSizes.get(cameraSize - 1);

    if (mSizePicture1.height < mSizePicture2.height)
       mSizePicture = supportedSizes.get(cameraSize - 1);
    else
       mSizePicture = supportedSizes.get(0);

parameters.setPictureSize(mSizePicture.width, mSizePicture.height);

这里,从固定为要捕获的图片尺寸的最大尺寸中获取每个移动设备支持的尺寸。

To capture maximum picture size from camera, i hope these simple steps will be quite useful

 public static Camera mCamera;

Camera.Parameters parameters = mCamera.getParameters();
  parameters.getSupportedPictureSizes();
List<Camera.Size> supportedSizes = parameters.getSupportedPictureSizes();
  mSizePicture1 = supportedSizes.get(0);
  int cameraSize = supportedSizes.size();
  mSizePicture2 = supportedSizes.get(cameraSize - 1);

    if (mSizePicture1.height < mSizePicture2.height)
       mSizePicture = supportedSizes.get(cameraSize - 1);
    else
       mSizePicture = supportedSizes.get(0);

parameters.setPictureSize(mSizePicture.width, mSizePicture.height);

Here, the supported size of the each mobile is taken, from that which size is maximum that is fixed as picture size to capture.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文