Mobile Camera and Album (1): Basic Call and Photo Cutting

Posted by shareaweb on Thu, 11 Jul 2019 00:36:56 +0200

There are many system controls in Android system that we often use in our daily development, such as keyboard, camera, album, telephone, short message and so on. Today, the Tao Chief speaks about the basic calls of mobile phone albums and cameras, the system's own cuttings and customized cuttings. Let's get up...

Basic Call of Camera

Jump to the camera interface:

    private void startCamera(){
        String status = Environment.getExternalStorageState();
        if (status.equals(Environment.MEDIA_MOUNTED)) {// Judging whether there is an SD card
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(
                    Environment.getExternalStorageDirectory(), TMP_PATH)));
            startActivityForResult(intent, CAMERA_PICKED_WITH_DATA);
        } else {
            Toast.makeText(MainActivity.this, "No, SD card",Toast.LENGTH_SHORT).show();
        }
    }


Data returned after calling the camera:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }

        switch (requestCode) {
            case CAMERA_PICKED_WITH_DATA:
                // When the camera program returns, it calls the image clipper again to trim the picture.
                picPath = Environment.getExternalStorageDirectory() + "/" + TMP_PATH;
                showPicture(null,picPath,doNext);
                break;
        }
    }

Basic Calls to Albums

Jump to Mobile Album:

    private void startPhoto(){
        // Mobile Phone Album
        Intent intent = new Intent();
        // Open Pictures screen Type to image
        intent.setType("image/*");
        // Use Intent.ACTION_GET_CONTENT for this Action
        intent.setAction(Intent.ACTION_GET_CONTENT);
        // Get the picture and return to the picture.
        startActivityForResult(intent, PHOTO_PICKED_WITH_DATA);
    }


Data returned after calling the album:

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }

        switch (requestCode) {
            case PHOTO_PICKED_WITH_DATA:
                Uri uri_ca = null;
                if (data != null && data.getData() != null) {
                    uri_ca = data.getData();
                } else {
                    if (photoUri != null) {
                        uri_ca = photoUri;
                    } else {
                        return;
                    }
                }
                picPath = PictureUtil.getPath(this, uri_ca);
                showPicture(uri_ca,picPath,doNext);
                break; 
        }
    }

Cut Photos

Cutting a photo is actually putting the selected photo in the album or the image returned from the camera into the cutting interface and returning to the photo display after cutting. Clipping photos can be customized or built into the system. The system's own cutting tool seems to be able to cut only the images returned by the album. The images returned by the camera are not supported. The length of work is insufficient (_), and no suitable method has been found. I hope you can tell me something about children's shoes. Thank you first. Custom Cut Path Length is only about the simplest Cut Path. As for some graphic tools, let's not introduce them.

System Cutting Tool

Call the camera/album to get the preferred image:

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_camera:
                doNext = "2show";
                startCamera();
                break;
            case R.id.btn_photo:
                doNext = "2show";
                startPhoto();
                break;
            case R.id.btn_system_cut_photo:
                doNext = "2system_cut";
                startPhoto();
                break;
        }
    }


Photos returned from the album:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }

        switch (requestCode) {
            case PHOTO_PICKED_WITH_DATA:
                Uri uri_ca = null;
                if (data != null && data.getData() != null) {
                    uri_ca = data.getData();
                } else {
                    if (photoUri != null) {
                        uri_ca = photoUri;
                    } else {
                        return;
                    }
                }
                picPath = PictureUtil.getPath(this, uri_ca);
                showPicture(uri_ca,picPath,doNext);
                break;
        }
    }


Pictures returned by System Cut Tool:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }

        switch (requestCode) {
            case PHOTO_PICKED_WITH_DATA:
                Uri uri_ca = null;
                if (data != null && data.getData() != null) {
                    uri_ca = data.getData();
                } else {
                    if (photoUri != null) {
                        uri_ca = photoUri;
                    } else {
                        return;
                    }
                }
                picPath = PictureUtil.getPath(this, uri_ca);
                showPicture(uri_ca,picPath,doNext);
                break;
            case CROP_RESULT_DATA:
                picPath = data.getStringExtra("crop_image_path");
                showPicture(null,picPath,"2show");
                break;
        }
    }

Custom Cut Photos

Call the camera/album to get the preferred image:

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_camera_to_cut:
                doNext = "2custom_cut";
                startCamera();
                break;
            case R.id.btn_photo_to_cut:
                doNext = "2custom_cut";
                startPhoto();
                break;
        }
    }


Photo album/camera selection

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }

        switch (requestCode) {
            case PHOTO_PICKED_WITH_DATA:
                Uri uri_ca = null;
                if (data != null && data.getData() != null) {
                    uri_ca = data.getData();
                } else {
                    if (photoUri != null) {
                        uri_ca = photoUri;
                    } else {
                        return;
                    }
                }
                picPath = PictureUtil.getPath(this, uri_ca);
                showPicture(uri_ca,picPath,doNext);
                break;
            case CAMERA_PICKED_WITH_DATA:

                // When the camera program returns, it calls the image clipper again to trim the picture.
                picPath = Environment.getExternalStorageDirectory() + "/" + TMP_PATH;
                showPicture(null,picPath,doNext);
                break;
            case CROP_RESULT_DATA:
                picPath = data.getStringExtra("crop_image_path");
                showPicture(null,picPath,"2show");
                break;
        }
    }

    private void showPicture(Uri uri,String filePath, String doNext){
        switch (doNext){
            case "2show":
                picFile = new File(filePath);
                picBitmap = PictureUtil.getBitmapThumbnail(picFile);
                picDrawable = new BitmapDrawable(picBitmap);
                if (picDrawable != null) {
                    iv_show.setImageDrawable(picDrawable);
                }
                break;
            case "2custom_cut":
                startCropImageActivity(filePath);
                break;
            case "2system_cut":
                startImageZoom(uri);
                break;
        }
    }


In the code above, the album and the photos returned by the camera are jumped to the picture cutting interface, which is implemented as follows:

public class ClipImageActivity extends Activity implements OnClickListener {
    public static String RESULT_PATH = "";
    private static final String KEY = "path";
    private ClipImageLayout mClipImageLayout = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.crop_image_layout);

        mClipImageLayout = (ClipImageLayout) findViewById(R.id.clipImageLayout);
        mClipImageLayout.setHorizontalPadding(100);// Set the clipping box padding value
        String path = getIntent().getStringExtra(KEY);

        // Some of the images returned by the system are rotated, others are not rotated, so processing
        int degreee = readBitmapDegree(path);
        Bitmap bitmap = createBitmap(path);
        if (bitmap != null) {
            if (degreee == 0) {
                mClipImageLayout.setImageBitmap(bitmap);
            } else {
                mClipImageLayout.setImageBitmap(rotateBitmap(degreee, bitmap));
            }
        } else {
            finish();
        }
        findViewById(R.id.okBtn).setOnClickListener(this);
        findViewById(R.id.cancleBtn).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
            case R.id.okBtn:
                Bitmap bitmap = mClipImageLayout.clip();
                RESULT_PATH = System.currentTimeMillis() + "";
                String path = Environment.getExternalStorageDirectory() + "/"
                        + ClipImageActivity.RESULT_PATH + ".jpg";

                saveBitmap(bitmap, path);

                Intent intent = new Intent();
                intent.putExtra("crop_image_path", path);
                setResult(RESULT_OK, intent);
                this.finish();
                break;
            case R.id.cancleBtn:
                this.finish();
                break;
        }
    }

    public static void startActivity(Activity activity, String path, int code) {
        Intent intent = new Intent(activity, ClipImageActivity.class);
        intent.putExtra(KEY, path);
        activity.startActivityForResult(intent, code);
    }

    /**
     * Save pictures
     *
     * @param bitmap
     * @param path
     */
    private void saveBitmap(Bitmap bitmap, String path) {
        File f = new File(path);
        if (f.exists()) {
            f.delete();
        }

        FileOutputStream fOut = null;
        try {
            f.createNewFile();
            fOut = new FileOutputStream(f);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
            fOut.flush();
        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            try {
                if (fOut != null)
                    fOut.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * create picture
     *
     * @param path
     * @return
     */
    private Bitmap createBitmap(String path) {

        if (path == null) {
            return null;
        }

        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inSampleSize = 1;
        opts.inJustDecodeBounds = false;
        opts.inPurgeable = true;
        opts.inInputShareable = true;
        opts.inDither = false;
        opts.inPurgeable = true;
        FileInputStream is = null;
        Bitmap bitmap = null;
        try {
            is = new FileInputStream(path);
            bitmap = BitmapFactory.decodeFileDescriptor(is.getFD(), null, opts);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                    is = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return bitmap;
    }

    /**
     * Rotation of read image
     *
     * @param path
     * @return
     */
    private int readBitmapDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * Rotating pictures
     *
     * @param angle
     * @param bitmap
     * @return
     */
    private Bitmap rotateBitmap(int angle, Bitmap bitmap) {
        // Rotating pictures
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        // Create a new picture
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, false);
        return resizedBitmap;
    }
}

Here the Taoist customizes a layout to cut pictures, but this method is not so perfect. Cutting can be achieved by measuring the path length, but the user experience is not so good when cutting large images. Next, I will paste the implementation, hoping that children's shoes can be improved...

public class ClipImageLayout extends RelativeLayout {
    private ClipZoomImageView mZoomImageView;
    private ClipImageBorderView mClipImageView;

    public ClipImageLayout(Context context) {
        super(context);
        init();
    }

    public ClipImageLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ClipImageLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        // Floating-point type calculator
//        floatEvaluator = new FloatEvaluator();
    }
    /**
     * Method function: Get child controls
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        // Simple exception handling
        if (getChildCount() != 2) {
            throw new IllegalArgumentException("SlideMenu only support 2 children!");
        }

        mClipImageView = (ClipImageBorderView) getChildAt(1);
        mZoomImageView = (ClipZoomImageView) getChildAt(0);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        measureChild(mClipImageView, widthMeasureSpec, heightMeasureSpec);
        measureChild(mZoomImageView, widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int left = 0;
        int top = 0;

        mClipImageView.layout(left,top,mClipImageView.getMeasuredWidth(), mClipImageView.getMeasuredHeight());
        mZoomImageView.layout(left,top,mZoomImageView.getMeasuredWidth(), mZoomImageView.getMeasuredHeight());
    }


    public void setImageDrawable(Drawable drawable) {
        mZoomImageView.setImageDrawable(drawable);
    }

    public void setImageBitmap(Bitmap bitmap) {
        mZoomImageView.setImageBitmap(bitmap);
    }

    /**
     * The method unit of setting margin for public announcement is dp
     *
     * @param mHorizontalPadding
     */
    public void setHorizontalPadding(int mHorizontalPadding) {
        mClipImageView.setHorizontalPadding(mHorizontalPadding);
        mZoomImageView.setHorizontalPadding(mHorizontalPadding);
    }

    /**
     * Cut pictures
     *
     * @return
     */
    public Bitmap clip() {
        return mZoomImageView.clip();
    }
}

As for the code involved, it is not posted one by one. If necessary, the Chancellor will post Demo to the end.

Data returned from custom cut diagrams:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }

        switch (requestCode) {
            case PHOTO_PICKED_WITH_DATA:
                Uri uri_ca = null;
                if (data != null && data.getData() != null) {
                    uri_ca = data.getData();
                } else {
                    if (photoUri != null) {
                        uri_ca = photoUri;
                    } else {
                        return;
                    }
                }
                picPath = PictureUtil.getPath(this, uri_ca);
                showPicture(uri_ca,picPath,doNext);
                break;
            case CAMERA_PICKED_WITH_DATA:

                // When the camera program returns, it calls the image clipper again to trim the picture.
                picPath = Environment.getExternalStorageDirectory() + "/" + TMP_PATH;
                showPicture(null,picPath,doNext);
                break;
            case CROP_RESULT_DATA:
                picPath = data.getStringExtra("crop_image_path");
                showPicture(null,picPath,"2show");
                break;
            case CUSTOM_CROP_RESULT_DATA:

                Uri uri = null;
                if (data != null && data.getData() != null) {
                    uri = data.getData();
                } else {
                    if (photoUri != null) {
                        uri = photoUri;
                    } else {
                        return;
                    }
                }
                picPath = PictureUtil.getPath(this, uri);
                if (picPath == null) {
                    return;
                }
                showPicture(null,picPath,"2show");
                break;
        }

    }

Here, the basic use of mobile cameras and albums has been introduced. There are some deficiencies that I hope to correct. I hope this blog can solve your doubts.
Mobile Photo Album and Camera Demo: CameraAndPhotoDemo

Topics: Mobile Android calculator