我想写一个模块,在点击一个按钮,相机打开,我可以点击和捕捉图像。如果我不喜欢图像,我可以删除它,然后点击另一个图像,然后选择图像,它应该返回并在活动中显示该图像。


当前回答

下面是我用来捕捉和保存相机图像然后显示到imageview的代码。您可以根据需要使用。

你必须保存相机图像到特定的位置,然后从该位置获取,然后将其转换为字节数组。

这里是打开捕捉相机图像活动的方法。

private static final int CAMERA_PHOTO = 111;
private Uri imageToUploadUri;

private void captureCameraImage() {
        Intent chooserIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File f = new File(Environment.getExternalStorageDirectory(), "POST_IMAGE.jpg");
        chooserIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
        imageToUploadUri = Uri.fromFile(f);
        startActivityForResult(chooserIntent, CAMERA_PHOTO);
    }

那么你的onActivityResult()方法应该是这样的。

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

            if (requestCode == CAMERA_PHOTO && resultCode == Activity.RESULT_OK) {
                if(imageToUploadUri != null){
                    Uri selectedImage = imageToUploadUri;
                    getContentResolver().notifyChange(selectedImage, null);
                    Bitmap reducedSizeBitmap = getBitmap(imageToUploadUri.getPath());
                    if(reducedSizeBitmap != null){
                        ImgPhoto.setImageBitmap(reducedSizeBitmap);
                        Button uploadImageButton = (Button) findViewById(R.id.uploadUserImageButton);
                          uploadImageButton.setVisibility(View.VISIBLE);                
                    }else{
                        Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show();
                    }
                }else{
                    Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show();
                }
            } 
        }

下面是onActivityResult()中使用的getBitmap()方法。我已经做了所有的性能改进,可以同时获得相机捕捉图像位图。

private Bitmap getBitmap(String path) {

        Uri uri = Uri.fromFile(new File(path));
        InputStream in = null;
        try {
            final int IMAGE_MAX_SIZE = 1200000; // 1.2MP
            in = getContentResolver().openInputStream(uri);

            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(in, null, o);
            in.close();


            int scale = 1;
            while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) >
                    IMAGE_MAX_SIZE) {
                scale++;
            }
            Log.d("", "scale = " + scale + ", orig-width: " + o.outWidth + ", orig-height: " + o.outHeight);

            Bitmap b = null;
            in = getContentResolver().openInputStream(uri);
            if (scale > 1) {
                scale--;
                // scale to max possible inSampleSize that still yields an image
                // larger than target
                o = new BitmapFactory.Options();
                o.inSampleSize = scale;
                b = BitmapFactory.decodeStream(in, null, o);

                // resize to desired dimensions
                int height = b.getHeight();
                int width = b.getWidth();
                Log.d("", "1th scale operation dimenions - width: " + width + ", height: " + height);

                double y = Math.sqrt(IMAGE_MAX_SIZE
                        / (((double) width) / height));
                double x = (y / height) * width;

                Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x,
                        (int) y, true);
                b.recycle();
                b = scaledBitmap;

                System.gc();
            } else {
                b = BitmapFactory.decodeStream(in);
            }
            in.close();

            Log.d("", "bitmap size - width: " + b.getWidth() + ", height: " +
                    b.getHeight());
            return b;
        } catch (IOException e) {
            Log.e("", e.getMessage(), e);
            return null;
        }
    }

希望能有所帮助!

其他回答

2021年5月,爪哇

在处理了本文旁边所述的必要权限后, 在manifest中添加:

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

    <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/provider_paths" />
    </provider>
....

其中${applicationId}是应用程序的包名,例如my.app.com。

在res - > xml > provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
 <paths>
  <external-files-path name="my_images" path="Pictures" />
  <external-path name="external_files" path="."/>
    <files-path
    name="files"   path="." />
    <external-cache-path
      name="images" path="." />
 </paths>

在活动:

private void onClickCaptureButton(View view) {
    Intent takePictureIntent_ = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent_.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile_ = null;
        try {
            photoFile_ = createImageFile();
        } catch (IOException ex) {
        }
        if(photoFile_!=null){
            picturePath=photoFile_.getAbsolutePath();
        }
        // Continue only if the File was successfully created
        if (photoFile_ != null) {
            Uri photoURI_ = FileProvider.getUriForFile(this,
               "my.app.com.fileprovider", photoFile_);
            takePictureIntent_.putExtra(MediaStore.EXTRA_OUTPUT, photoURI_);
            startActivityForResult(takePictureIntent_, REQUEST_IMAGE_CAPTURE);
        }
    }
}

还有三招:

...
private static String picturePath;
private static final int REQUEST_IMAGE_CAPTURE = 2;
...
private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp_ = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new 
      Date());
    String imageFileName_ = "JPEG_" + timeStamp_ + "_";
    File storageDir_ = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File image_ = File.createTempFile(
            imageFileName_,  /* prefix */
            ".jpg",         /* suffix */
            storageDir_      /* directory */
    );

    // Save a file: path for use with ACTION_VIEW intents
    picturePath= image_.getAbsolutePath();
    return image_;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
   if(requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK 
   ){

        try {
            File file_ = new File(picturePath);
            Uri uri_ = FileProvider.getUriForFile(this,
                    "my.app.com.fileprovider", file_);
            rasm.setImageURI(uri_);
        } catch (/*IO*/Exception e) {
            e.printStackTrace();
        }
    }
}

and

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putString("safar", picturePath);
    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}

and:

 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        picturePath = savedInstanceState.getString("safar");
    }
 ....
}

在这里你可以打开相机或图库,并设置选定的图像到imageview

private static final String IMAGE_DIRECTORY = "/YourDirectName";
private Context mContext;
private CircleImageView circleImageView;  // imageview
private int GALLERY = 1, CAMERA = 2;

在清单中添加权限

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="ANDROID.PERMISSION.READ_EXTERNAL_STORAGE" />

在onCreate ()

    requestMultiplePermissions(); // check permission 

    circleImageView = findViewById(R.id.profile_image);
    circleImageView.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            showPictureDialog();
        }
    });

显示选项对话框(用于从相机或图库中选择图像)

private void showPictureDialog() {
    AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
    pictureDialog.setTitle("Select Action");
    String[] pictureDialogItems = {"Select photo from gallery", "Capture photo from camera"};
    pictureDialog.setItems(pictureDialogItems,
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    switch (which) {
                        case 0:
                            choosePhotoFromGallary();
                            break;
                        case 1:
                            takePhotoFromCamera();
                            break;
                    }
                }
            });
    pictureDialog.show();
}

从图库获取照片

public void choosePhotoFromGallary() {
    Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(galleryIntent, GALLERY);
}

从相机中获取照片

private void takePhotoFromCamera() {
    Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, CAMERA);
}

一旦图像被选中或捕获,

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

    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == this.RESULT_CANCELED) {
        return;
    }
    if (requestCode == GALLERY) {
        if (data != null) {
            Uri contentURI = data.getData();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI);
                String path = saveImage(bitmap);
                Toast.makeText(getApplicationContext(), "Image Saved!", Toast.LENGTH_SHORT).show();
                circleImageView.setImageBitmap(bitmap);

            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(getApplicationContext(), "Failed!", Toast.LENGTH_SHORT).show();
            }
        }

    } else if (requestCode == CAMERA) {
        Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
        circleImageView.setImageBitmap(thumbnail);
        saveImage(thumbnail);
        Toast.makeText(getApplicationContext(), "Image Saved!", Toast.LENGTH_SHORT).show();
    }
}

现在是存储图片的时候了

public String saveImage(Bitmap myBitmap) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
    File wallpaperDirectory = new File(Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
    if (!wallpaperDirectory.exists()) {  // have the object build the directory structure, if needed.
        wallpaperDirectory.mkdirs();
    }

    try {
        File f = new File(wallpaperDirectory, Calendar.getInstance().getTimeInMillis() + ".jpg");
        f.createNewFile();
        FileOutputStream fo = new FileOutputStream(f);
        fo.write(bytes.toByteArray());
        MediaScannerConnection.scanFile(this,
                new String[]{f.getPath()},
                new String[]{"image/jpeg"}, null);
        fo.close();
        Log.d("TAG", "File Saved::---&gt;" + f.getAbsolutePath());

        return f.getAbsolutePath();
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    return "";
}

请求许可

    private void requestMultiplePermissions() {
    Dexter.withActivity(this)
            .withPermissions(
                    Manifest.permission.CAMERA,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE)
            .withListener(new MultiplePermissionsListener() {
                @Override
                public void onPermissionsChecked(MultiplePermissionsReport report) {
                    if (report.areAllPermissionsGranted()) {  // check if all permissions are granted
                        Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show();
                    }

                    if (report.isAnyPermissionPermanentlyDenied()) { // check for permanent denial of any permission
                        // show alert dialog navigating to Settings
                        //openSettingsDialog();
                    }
                }

                @Override
                public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
                    token.continuePermissionRequest();
                }
            }).
            withErrorListener(new PermissionRequestErrorListener() {
                @Override
                public void onError(DexterError error) {
                    Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show();
                }
            })
            .onSameThread()
            .check();
}

坏的质量

根据我的经验,如果我们使用

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, RESULT_ADD_PHOTO);

和处理onActivityResult()

Bitmap thumbnail= (Bitmap) data.getExtras().get("data");

它只会给你一个缩略图,当然有一个坏的质量。

不错的质量

您可以显示相机和保存您的图像文件在公共目录,例如在文档目录

在onClick()中使用这个

String imagePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) +
                File.separator + "your_image_name.jpeg";
Intent i =new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageFile = new File(imagePath );
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
startActivityForResult(i, RESULT_ADD_PHOTO);

在onActivityResult()中

Bitmap imageBitmap1 = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap imageBitmap = Bitmap.createBitmap(imageBitmap1, 0, 0, imageBitmap1.getWidth(), imageBitmap1.getHeight(), matrix, true);
binding.imageView.setImageBitmap(imageBitmap);

我使用postRotate(),因为在我的代码中,图像结果向左旋转,所以我需要将其旋转90

你可以使用此代码onClick监听器(你可以使用ImageView或按钮)

image.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                startActivityForResult(takePictureIntent, 1);
            }
        }
    });

在imageView中显示

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
        bitmap = (Bitmap) extras.get("data");
        image.setImageBitmap(bitmap);

    }
}

注意:将此插入舱单

<uses-feature android:name="android.hardware.camera" android:required="true" />

你得好好研究一下相机。(我认为要做到你想要的,你必须保存当前的图像到你的应用程序,在那里做选择/删除,然后召回相机再试一次,而不是直接在相机内部重试。)