Set Camera Size – Parameters vs Intent?

I am currently using an intent to take a picture, like this:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
intent.putExtra("return-data", true);
startActivityForResult(intent, CAMERA_REQUEST);

But I really need to set the image size as close to a square as possible. So after researching it seems you need to do something like this:

  • android:layout_gravity doesn't work as expected
  • Android: Generate random color on click?
  • Example of Camera preview using SurfaceTexture in Android
  • Back button on Android Phones
  • Unable to resolve target 'android-XX'
  • Android MediaRecorder stop() not being called
  • Camera camera = Camera.open();
    Parameters params = camera.getParameters();
    List<Camera.Size> sizes = params.getSupportedPictureSizes();
    
    // Once you will see the supported Sizes, you can define them with the method :
    
    setPictureSize(int width, int height);
    

    My questions are, do these work together or is it an either/or? Which method works best for my needs?

    Again, I have 96px by 96px box for user profile pics. After user takes the picture I want the image to fill entire box without stretching. Is the best way to set size at the point of picture being taken, or alter the imageView or bitmap (or …?) after the fact? OR, should I just let the users crop the picture and I can define the cropping area dimensions?

    Edit: See bounty for updated question.

  • Croping image in android using opencv
  • Support library VectorDrawable Resources$NotFoundException
  • Restful API service
  • How to re-authenticate a user on Firebase with Google Provider?
  • EditText with suggestion list below
  • In Android, how do I smoothly fade the background from one color to another? (How to use threads)
  • 4 Solutions collect form web for “Set Camera Size – Parameters vs Intent?”

    This code allows me to pick image from gallery. Crop and use my aspect ratio. I did similar code for using camera. After user takes picture, it immediately launches an activity to crop the picture.

      Intent photoPickerIntent = new Intent(
                            Intent.ACTION_PICK,
                            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    photoPickerIntent.setType("image/*");
                    photoPickerIntent.putExtra("crop", "true");
                    photoPickerIntent.putExtra("outputX", 150);
                    photoPickerIntent.putExtra("outputY", 150);
                    photoPickerIntent.putExtra("aspectX", 1);
                    photoPickerIntent.putExtra("aspectY", 1);
                    photoPickerIntent.putExtra("scale", true);
                    photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
                    photoPickerIntent.putExtra("outputFormat",
                            Bitmap.CompressFormat.JPEG.toString());
                    startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);
    

    You can use Bitmap.createScaleBitmap(Bitmap src, int destWidth, int destHeight, boolean filter) to resize a bitmap

    Do these work together or is it an either/or? Which method works best for my needs?

    No, they do not work together. When you use the camera with an Intent, you are asking the system to take a picture for you (i.e. the user gets prompted with the default camera app and takes a picture or chooses one from gallery).

    When you use the second approach, you create your own Camera object, which is much more customizable than the first one.

    With the first method you will have to scale the image afterwards, while with the second, you can take the picture directly in the correct size, so the main difference is that the first is controlled by android, and the second by your app directly, so the second method works best for your needs. if you don’t want to scale afterwards.

    If you’re going to scale anyway (read below), then it doesn’t matter which approach you use to take the picture, I’d say in that case, use the default app.

    Is the best way to set size at the point of picture being taken, or alter the imageView or bitmap (or …?) after the fact? OR, should I just let the users crop the picture and I can define the cropping area dimensions?

    That depends on your needs. In the first case your app alters the picture taken, so you choose which portion of the original picture will be the final 96×96 picture. The problem with this method is that you can accidentally crop/strech/manipulate the image in a wrong -or at least, unexpected- manner for the user (i.e. removing part of their face).

    When you use the second method, you are providint the user with the freedom to choose what part of the picture they want.

    If you are able to automatically detect the best portion of the original image, you should go with the first method, but as you are actually asking which is the best method, you should really go with the second one, because it provides more flexibility to the end user.

    (1) how can it be auto cropped to fit my ImageView (96dp x 96dp),

    It seems like you already have a solution for getting the crop correct. If you want to convert density pixel unit to pixel unit that corresponds to the phone, you need to use the

    public int dpToPixel(int dp) {
    Resources r = getResources();
    float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
    }
    

    So you can use following as extra

    photoPickerIntent.putExtra("outputX", dpToPixel(96));
    photoPickerIntent.putExtra("outputY", dpToPixel(96));
    

    (2) How can I shrink the picture in size (make a new bitmap?). These need to be loaded quickly on ListViews. So instead of a 1MB pic being upload, I need one more like 2,000k.

    If you use image that are around the size of 96dp, you don’t really need to worry about image sizes. Creating and destroying new bitmaps is usually very dangerous when you try to do multiple of them in an activity. You can easily run into issues such as “Out of Memory” issues. Therefore, it is more advised to use Uri’s instead. So, save the uri that you are putting in the intent, and make a list of uris’ to display on the listview however you want.

    On a imageview, it is setImageURI(Uri uri).

    Hope that answers all your questions.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.