Capture Image from Camera and Display in Activity

前端 未结 16 1008
悲&欢浪女
悲&欢浪女 2020-11-21 06:43

I want to write a module where on a click of a button the camera opens and I can click and capture an image. If I don\'t like the image I can delete it and click one more i

相关标签:
16条回答
  • 2020-11-21 07:09

    Here is the complete code:

    package com.example.cameraa;
    import android.app.Activity;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.net.Uri;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    
    public class MainActivity extends Activity {
    
    
    
    
            Button btnTackPic;
            Uri photoPath;
            ImageView ivThumbnailPhoto;
    
            static int TAKE_PICTURE = 1;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
    
                // Get reference to views
    
                btnTackPic = (Button) findViewById(R.id.bt1);
                ivThumbnailPhoto = (ImageView) findViewById(R.id.imageView1);
    
    
    
    
         btnTackPic.setOnClickListener(new View.OnClickListener() {
    
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
    
    
                    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
                    startActivityForResult(cameraIntent, TAKE_PICTURE); 
                }
    
    
    
    
        });
    
            } 
    
            @Override
            protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    
    
                    if (requestCode == TAKE_PICTURE && resultCode == RESULT_OK) {  
                        Bitmap photo = (Bitmap)intent.getExtras().get("data"); 
                       ivThumbnailPhoto.setImageBitmap(photo);
                    ivThumbnailPhoto.setVisibility(View.VISIBLE);
    
    
    
                }
            }
    }
    

    Remember to add permissions for the camera too.

    0 讨论(0)
  • 2020-11-21 07:09

    Bitmap photo = (Bitmap) data.getExtras().get("data"); gets a thumbnail from camera. There is an article about how to store a picture in external storage from camera. useful link

    0 讨论(0)
  • 2020-11-21 07:09

    Please, follow this example with this implementation by using Kotlin and Andoirdx support:

    button1.setOnClickListener{
            file = getPhotoFile()
            val uri: Uri = FileProvider.getUriForFile(applicationContext, "com.example.foto_2.filrprovider", file!!)
            captureImage.putExtra(MediaStore.EXTRA_OUTPUT, uri)
    
            val camaraActivities: List<ResolveInfo> = applicationContext.getPackageManager().queryIntentActivities(captureImage, PackageManager.MATCH_DEFAULT_ONLY)
    
            for (activity in camaraActivities) {
                applicationContext.grantUriPermission(activity.activityInfo.packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
            }
    
            startActivityForResult(captureImage, REQUEST_PHOTO)
        }
    

    And the activity result:

    if (requestCode == REQUEST_PHOTO) {
            val uri = FileProvider.getUriForFile(applicationContext, "com.example.foto_2.filrprovider", file!!)
            applicationContext.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
            imageView1.viewTreeObserver.addOnGlobalLayoutListener {
                width = imageView1.width
                height = imageView1.height
                imageView1.setImageBitmap(getScaleBitmap(file!!.path , width , height))
            }
            if(width!=0&&height!=0){
                imageView1.setImageBitmap(getScaleBitmap(file!!.path , width , height))
            }else{
                val size = Point()
                this.windowManager.defaultDisplay.getSize(size)
                imageView1.setImageBitmap(getScaleBitmap(file!!.path , size.x , size.y))
            }
    
        }
    

    You can get more detail in https://github.com/joelmmx/take_photo_kotlin.git

    I hope it helps you!

    0 讨论(0)
  • 2020-11-21 07:14

    Update (2020)

    Google has added a new ActivityResultRegistry API that "lets you handle the startActivityForResult() + onActivityResult() as well as requestPermissions() + onRequestPermissionsResult() flows without overriding methods in your Activity or Fragment, brings increased type safety via ActivityResultContract, and provides hooks for testing these flows" - source.

    The API was added in androidx.activity 1.2.0-alpha02 and androidx.fragment 1.3.0-alpha02.

    So you are now able to do something like:

    val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { success: Boolean ->
        if (success) {
            // The image was saved into the given Uri -> do something with it
        }
    }
    
    val imageUri: Uri = ...
    button.setOnClickListener {
        takePicture.launch(imageUri)
    }
    

    Take a look at the documentation to learn how to use the new Activity result API: https://developer.android.com/training/basics/intents/result#kotlin

    There are many built-in ActivityResultContracts that allow you to do different things like pick contacts, request permissions, take pictures or take videos. You are probably interested in the ActivityResultContracts.TakePicture shown above.

    Note that androidx.fragment 1.3.0-alpha04 deprecates the startActivityForResult() + onActivityResult() and requestPermissions() + onRequestPermissionsResult() APIs on Fragment. Hence it seems that ActivityResultContracts is the new way to do things from now on.


    Original answer (2015)

    It took me some hours to get this working. The code it's almost a copy-paste from developer.android.com, with a minor difference.

    Request this permission on the AndroidManifest.xml:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    

    On your Activity, start by defining this:

    static final int REQUEST_IMAGE_CAPTURE = 1;
    private Bitmap mImageBitmap;
    private String mCurrentPhotoPath;
    private ImageView mImageView;
    

    Then fire this Intent in an onClick:

    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (cameraIntent.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File
            Log.i(TAG, "IOException");
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
            startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);
        }
    }
    

    Add the following support method:

    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 = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  // prefix
                ".jpg",         // suffix
                storageDir      // directory
        );
    
        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = "file:" + image.getAbsolutePath();
        return image;
    }
    

    Then receive the result:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            try {
                mImageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(mCurrentPhotoPath));
                mImageView.setImageBitmap(mImageBitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    What made it work is the MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(mCurrentPhotoPath)), which is different from the code from developer.android.com. The original code gave me a FileNotFoundException.

    0 讨论(0)
  • 2020-11-21 07:14

    I created a dialog with the option to choose Image from gallery or camera. with a callback as

    • Uri if the image is from the gallery
    • String as a file path if the image is captured from the camera.
    • Image as File the image chosen from camera needs to be uploaded on the internet as Multipart file data

    At first we to define permission in AndroidManifest as we need to write external store while creating a file and reading images from gallery

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

    Create a file_paths xml in app/src/main/res/xml/file_paths.xml

    with path

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

    Then we need to define file provier to generate Content uri to access file stored in external storage

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

    Dailog Layout

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.50" />
    
        <ImageView
            android:id="@+id/gallery"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="32dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="32dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline2"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/ic_menu_gallery" />
    
        <ImageView
            android:id="@+id/camera"
            android:layout_width="48dp"
            android:layout_height="0dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="32dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="32dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/guideline2"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/ic_menu_camera" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    ImagePicker Dailog

    public class ImagePicker extends BottomSheetDialogFragment {
    ImagePicker.GetImage getImage;
    public ImagePicker(ImagePicker.GetImage getImage, boolean allowMultiple) {
        this.getImage = getImage;
    }
    File cameraImage;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.bottom_sheet_imagepicker, container, false);
        view.findViewById(R.id.camera).setOnClickListener(new View.OnClickListener() {@
            Override
            public void onClick(View view) {
                if(ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    requestPermissions(new String[] {
                        Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE
                    }, 2000);
                } else {
                    captureFromCamera();
                }
            }
        });
        view.findViewById(R.id.gallery).setOnClickListener(new View.OnClickListener() {@
            Override
            public void onClick(View view) {
                if(ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    requestPermissions(new String[] {
                        Manifest.permission.READ_EXTERNAL_STORAGE
                    }, 2000);
                } else {
                    startGallery();
                }
            }
        });
        return view;
    }
    public interface GetImage {
        void setGalleryImage(Uri imageUri);
        void setCameraImage(String filePath);
        void setImageFile(File file);
    }@
    Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == Activity.RESULT_OK) {
            if(requestCode == 1000) {
                Uri returnUri = data.getData();
                getImage.setGalleryImage(returnUri);
                Bitmap bitmapImage = null;
            }
            if(requestCode == 1002) {
                if(cameraImage != null) {
                    getImage.setImageFile(cameraImage);
                }
                getImage.setCameraImage(cameraFilePath);
            }
        }
    }
    private void startGallery() {
        Intent cameraIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        cameraIntent.setType("image/*");
        if(cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
            startActivityForResult(cameraIntent, 1000);
        }
    }
    private String cameraFilePath;
    private File createImageFile() throws IOException {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "Camera");
        File image = File.createTempFile(imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ );
        cameraFilePath = "file://" + image.getAbsolutePath();
        cameraImage = image;
        return image;
    }
    private void captureFromCamera() {
        try {
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID + ".provider", createImageFile()));
            startActivityForResult(intent, 1002);
        } catch(IOException ex) {
            ex.printStackTrace();
        }
    }
    

    }

    Call in Activity or fragment like this Define ImagePicker in Fragment/Activity

    ImagePicker imagePicker;
    

    Then call dailog on click of button

          imagePicker = new ImagePicker(new ImagePicker.GetImage() {
                @Override
                public void setGalleryImage(Uri imageUri) {
    
                    Log.i("ImageURI", imageUri + "");
    
                    String[] filePathColumn = {MediaStore.Images.Media.DATA};
    
                    Cursor cursor = getContext().getContentResolver().query(imageUri, filePathColumn, null, null, null);
                    assert cursor != null;
                    cursor.moveToFirst();
    
                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    mediaPath = cursor.getString(columnIndex);
                    // Set the Image in ImageView for Previewing the Media
                    imagePreview.setImageBitmap(BitmapFactory.decodeFile(mediaPath));
                    cursor.close();
    
                }
    
                @Override
                public void setCameraImage(String filePath) {
    
                    mediaPath =filePath;
                    Glide.with(getContext()).load(filePath).into(imagePreview);
    
                }
    
                @Override
                public void setImageFile(File file) {
    
                    cameraImage = file;
    
                }
            }, true);
            imagePicker.show(getActivity().getSupportFragmentManager(), imagePicker.getTag());
    
    0 讨论(0)
  • 2020-11-21 07:18

    In Activity:

    @Override
        protected void onCreate(Bundle savedInstanceState) {
                     image = (ImageView) findViewById(R.id.imageButton);
            image.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    try {
                    SimpleDateFormat sdfPic = new SimpleDateFormat(DATE_FORMAT);
                    currentDateandTime = sdfPic.format(new Date()).replace(" ", "");
                    File imagesFolder = new File(IMAGE_PATH, currentDateandTime);
                    imagesFolder.mkdirs();
                    Random generator = new Random();
                    int n = 10000;
                    n = generator.nextInt(n);
                    String fname = IMAGE_NAME + n + IMAGE_FORMAT;
                    File file = new File(imagesFolder, fname);
                    outputFileUri = Uri.fromFile(file);
                    cameraIntent= new Intent(
                            android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
                                    startActivityForResult(cameraIntent, CAMERA_DATA);
                    }catch(Exception e) {
                        e.printStackTrace();
                    }
    
                }
            });
               @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            switch(requestCode) {
            case CAMERA_DATA :
                    final int IMAGE_MAX_SIZE = 300;
                    try {
                        // Bitmap bitmap;
                        File file = null;
                        FileInputStream fis;
                        BitmapFactory.Options opts;
                        int resizeScale;
                        Bitmap bmp;
                        file = new File(outputFileUri.getPath());
                        // This bit determines only the width/height of the
                        // bitmap
                        // without loading the contents
                        opts = new BitmapFactory.Options();
                        opts.inJustDecodeBounds = true;
                        fis = new FileInputStream(file);
                        BitmapFactory.decodeStream(fis, null, opts);
                        fis.close();
    
                        // Find the correct scale value. It should be a power of
                        // 2
                        resizeScale = 1;
    
                        if (opts.outHeight > IMAGE_MAX_SIZE
                                || opts.outWidth > IMAGE_MAX_SIZE) {
                            resizeScale = (int) Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE/ (double) Math.max(opts.outHeight, opts.outWidth)) / Math.log(0.5)));
                        }
    
                        // Load pre-scaled bitmap
                        opts = new BitmapFactory.Options();
                        opts.inSampleSize = resizeScale;
                        fis = new FileInputStream(file);
                        bmp = BitmapFactory.decodeStream(fis, null, opts);
                        Bitmap getBitmapSize = BitmapFactory.decodeResource(
                                getResources(), R.drawable.male);
                        image.setLayoutParams(new RelativeLayout.LayoutParams(
                                200,200));//(width,height);
                        image.setImageBitmap(bmp);
                        image.setRotation(90);
                        fis.close();
    
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        bmp.compress(Bitmap.CompressFormat.JPEG, 70, baos);
                        imageByte = baos.toByteArray();
                        break;
                    } catch (FileNotFoundException e) {
    
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
    

    in layout.xml:

    enter code here
    <RelativeLayout
            android:id="@+id/relativeLayout2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
    
    
            <ImageView
                android:id="@+id/imageButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
    
                                android:src="@drawable/XXXXXXX"
                android:textAppearance="?android:attr/textAppearanceSmall" />
    

    in manifest.xml:

        <uses-permission android:name="android.permission.CAMERA" />   <uses-feature android:name="android.hardware.camera" />
    

    0 讨论(0)
提交回复
热议问题