How to get full size picture and thumbnail from Ca

2020-08-01 05:37发布

问题:

I've been needing to get a solution for this problem. I've already searched and tested many solutions from this community but anyone was fit for helping me.

I have two activities, the first one takes a picture and sends it to another which has an ImageView to receive that (until here i'm getting problems) and a query to insert the file path in the database (the code which do this last part is well).

I guess its better for the View load an Image Low Resolution as a Thumbnail. Therefore, to save into the database i wanna get the whole path from a full size picture.

Whether possible the images must to be inside a specific directory that i can choose the name given parameters to the function.

Perhaps anyone also knows how to set the smallest resolution from the camera automatically.

回答1:

If you want to have the full size picture, you need to provide the URI on the Intent's extra Data. Doing it this way, no thumbnail is returned, so you need to generate your own.

For modifying the second Activity, you can update your ImageView with the path saved in your DB using the onResume() method of your second Activity; just be sure to validate it's not null.

public static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;

private boolean hasCamera(){
    return getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
}

public void takePicture(){

    // Check if there is a camera.
    if(!hasCamera())
    {
        Toast.makeText(getActivity(), "This device does not have a camera.", Toast.LENGTH_SHORT).show();
        return;
    }

    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    //TODO: Set this to the path you want to save, 
    //you can use Environment.getExternalStorageDirectory() 
    //and a TimeStamp to generate an unique name
    //Save the path to your DB
    Uri exampleUri  = Uri.parse("file:///sdcard/photo.jpg");
    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, exampleUri);
    startActivityForResult(takePictureIntent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}



@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
    {
        if (resultCode == RESULT_OK)
        {
            // Image captured and saved to fileUri specified in the Intent
            Toast.makeText(this, "Image saved", Toast.LENGTH_LONG).show();

           //If you no use onResume(); to update the ImageView
           //Another way is calling here your method for update the ImageView
           //with the path of your DB
        }
        else
        {
            if (resultCode == RESULT_CANCELED)
            {
                // User cancelled the image capture
                // So need to Delete the path from DB
            }
        }
    }

An easy way to generate thumbnails:

Bitmap thumbImage = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(imagePath), THUMBSIZE, THUMBSIZE);
imageView.setImageBitmap(thumbImage);


回答2:

Example of get full size picture and thumbnail with camera intent

first declare a button to take a picture...

Button takePhoto = (Button) findViewById(R.id.btn_takePhoto);
        takePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    startActivityForResult(cameraIntent, 1);
            }
        });

Then in onActivityResult we are getting the data...

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

        if(requestCode == 1 && resultCode == Activity.RESULT_OK){

                //path from full size image
                Cursor cursor = MyActivity.this.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");

                Bitmap fullsize;
                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) {
                        System.out.println("path: "+photoPath); //path from image full size
                        fullsize = decodeSampledBitmap(photoPath);//here is the bitmap of image full size
                    }
                }

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


                // thumbnail
                Bitmap thumbnail;
                thumbnail = (Bitmap) data.getExtras().get("data");
                // do whatever you want with the Bitmap .... thumbnail
            }
        }

For memory leak use this functions

private 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;
    } 



private Bitmap decodeSampledBitmap(String pathName,
                                   int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(pathName, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(pathName, options);
}

//I added this to have a good approximation of the screen size:
private Bitmap decodeSampledBitmap(String pathName) {
    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int width = size.x;
    int height = size.y;
    return decodeSampledBitmap(pathName, width, height);
}

Note: decodeSampledBitmap is a function to better performance in memory leak, like when you get OOM(out of memory)....

Loading Large Bitmaps Efficiently