8

I want crop an image in my application.I tried a lot but not succeed.Its challenge to android developer. Is there any idea or reference to implement the features move,scale and crop the image in android like facebook upload profile pic. Now i am able to move, scale and crop and the image.But not consistant like facebook.I want to set fix image scale based on orientation.I attached the screen shot-3.

My code as below:-

crop_image.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/flCrop"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <ImageView
            android:id="@+id/img"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scaleType="matrix"
            android:src="@drawable/nature" />

        <ImageView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_gravity="center"
            android:scaleType="fitXY"
            android:src="@drawable/blur_with_frame"
            android:visibility="visible" />

        <ImageView
            android:id="@+id/troll_face"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="10dp"
            android:layout_gravity="bottom" />
    </FrameLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal" >

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="btnSelectPic"
            android:layout_marginRight="10dp"
            android:text="select Pic" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:onClick="btnCrop"
            android:text="Crop" />
    </LinearLayout>

</LinearLayout>

MainActivity.java

package com.hotveryspicy.maskimage;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.net.Uri;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

import com.ipaulpro.afilechooser.utils.FileUtils;

public class MainActivity extends Activity implements OnTouchListener{
    ImageView img;
    FrameLayout flCrop;

    int framWidth = 0;
    int framHeight = 0;

    int imageHeight ;
    int imageWidth ;

    int cropImageWidth = 320;
    int cropImageHeight = 263;

    public static int SELECT_PHOTO =0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.crop_image);
        img = (ImageView) findViewById(R.id.img);
        flCrop = (FrameLayout) findViewById(R.id.flCrop);
        img.setOnTouchListener(this);


    }

    public void btnCrop(View v) {
        ImageView troll_face = (ImageView) findViewById(R.id.troll_face);
        makeMaskImage(troll_face, R.drawable.nature);
    }

    public void btnSelectPic(View v){
        Intent intent = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, 0);
    }

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

        switch (resultCode) {
        case RESULT_OK:
            Uri targetUri = data.getData();

            final String path = FileUtils.getPath(this, targetUri);

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;

            Bitmap bitmap = null;
            try {

                bitmap = BitmapFactory
                        .decodeFile(path);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            imageHeight = options.outHeight;
            imageWidth = options.outWidth;

            img.setOnTouchListener(MainActivity.this);

            img.setImageBitmap(bitmap);

            break;
        }
    }

    // Method of creating mask runtime
    public void makeMaskImage(ImageView mImageView, int mContent) {

        flCrop.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(flCrop.getDrawingCache());
        flCrop.setDrawingCacheEnabled(false);

        Log.e("TEST", "Frame W : " + framWidth + " H : " + framHeight);
        Log.e("TEST",
                "Bitmap W : " + bitmap.getWidth() + " H : "
                        + bitmap.getHeight());

        Bitmap result = Bitmap.createBitmap(bitmap, (framWidth / 2)
                - (cropImageWidth / 2) +1, (framHeight / 2)
                - (cropImageHeight / 2), cropImageWidth -2, cropImageHeight);
        mImageView.setImageBitmap(result);
        mImageView.setScaleType(ScaleType.CENTER);
        // mImageView.setBackgroundResource(R.drawable.frame);
    }





    @Override
      public boolean onTouch(View v, MotionEvent event) {
            // handle touch events here
            ImageView view = (ImageView) v;
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    savedMatrix.set(matrix);
                    start.set(event.getX(), event.getY());
                    mode = DRAG;
                    lastEvent = null;
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
                    oldDist = spacing(event);
                    if (oldDist > 10f) {
                        savedMatrix.set(matrix);
                        midPoint(mid, event);
                        mode = ZOOM;
                    }
                    lastEvent = new float[4];
                    lastEvent[0] = event.getX(0);
                    lastEvent[1] = event.getX(1);
                    lastEvent[2] = event.getY(0);
                    lastEvent[3] = event.getY(1);
                    d = rotation(event);
                    Log.e("MainActivity","MainActivity down d = "+d);
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_POINTER_UP:
                    mode = NONE;
                    lastEvent = null;
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mode == DRAG) {
                        matrix.set(savedMatrix);
                        float dx = event.getX() - start.x;
                        float dy = event.getY() - start.y;
                        Log.e("TEST","Dx : "+ dx+" Dy : "+ dy);
                        matrix.postTranslate(dx, dy);
                    } else if (mode == ZOOM) {
                        float newDist = spacing(event);
                        if (newDist > 10f) {
                            matrix.set(savedMatrix);
                            float scale = (newDist / oldDist);
                            matrix.postScale(scale, scale, mid.x, mid.y);
                        }
                        if (lastEvent != null && event.getPointerCount() == 3) {
                            newRot = rotation(event);
                            Log.e("MainActivity","MainActivity move d= "+d);
                            float r = newRot - d;
                            float[] values = new float[9];
                            matrix.getValues(values);
                            float tx = values[2];
                            float ty = values[5];
                            float sx = values[0];
                            float xc = (view.getWidth() / 2) * sx;
                            float yc = (view.getHeight() / 2) * sx;
                            matrix.postRotate(r, tx + xc, ty + yc);
                        }
                    }
                    break;
                 default:
                     view.setImageMatrix(matrix);
                     return true;
            }
            view.setImageMatrix(matrix);
            return true;
        }

        /**
         * Determine the space between the first two fingers
         */
        private float spacing(MotionEvent event) {
            float x = event.getX(0) - event.getX(1);
            float y = event.getY(0) - event.getY(1);
            return FloatMath.sqrt(x * x + y * y);
        }

        /**
         * Calculate the mid point of the first two fingers
         */
        private void midPoint(PointF point, MotionEvent event) {
            float x = event.getX(0) + event.getX(1);
            float y = event.getY(0) + event.getY(1);
            point.set(x / 2, y / 2);
        }

        /**
         * Calculate the degree to be rotated by.
         *
         * @param event
         * @return Degrees
         */
        private float rotation(MotionEvent event) {
            double delta_x = (event.getX(0) - event.getX(1));
            double delta_y = (event.getY(0) - event.getY(1));
            double radians = Math.atan2(delta_y, delta_x);
            return (float) Math.toDegrees(radians);
        }
        // these matrices will be used to move and zoom image
        private static Matrix matrix = new Matrix();
        private static Matrix savedMatrix = new Matrix();
        // we can be in one of these 3 states
        private static final int NONE = 0;
        private static final int DRAG = 1;
        private static final int ZOOM = 2;
        private int mode = NONE;
        // remember some things for zooming
        private PointF start = new PointF();
        private PointF mid = new PointF();
        private float oldDist = 1f;
        private float d = 0f;
        private float newRot = 0f;
        private float[] lastEvent = null;

        boolean flag ;
}

Looking my demo like:-

Screenshot-1 Screenshot-1

When zoom-out its looking as below image:- Screenshot-2 Screenshot-2

What exactly i am looking the solution :- Screenshot-3

Screenshot-3

If anyone have idea.Please help me.Thanks in advance...

Jagdish
  • 2,418
  • 4
  • 25
  • 51

3 Answers3

2

I had a similar requirement. Created a cropping component using modified Photoview and Cropper library. User can select image from Gallery or take a picture from Camera and then crop the image with move and scale, similar to Facebook profile picture cropping. Sharing the project on github.

Please check the github project here: https://github.com/ozeetee/AndroidImageZoomCrop

Ozeetee
  • 126
  • 1
  • 5
  • thank you for the library it works like charm in square image cropping however I tried doing the rectangular cropping but photoview is ignoring the image bounds – Aashish Bhatnagar Jun 13 '17 at 11:31
0

I don't fully understand what you are trying to accomplish. I have been working on something similar, I think.


https://github.com/crystalpal/cropper


What this does: Reads an image from storage, displays it along with a cropping rectangle, let's you crop the selected area, and saves the cropped image. You can adjust the size of the cropper and the size of the saved image.

Using an intent, pass the file of the image to the new activity. From there, everything should be automatic.

Note:this project was written in Android 4.2, code is documented, but a decent knowledge of Android is recommended. The project uses the qoppa pdf library.

JorenV
  • 352
  • 3
  • 16
0

I have taken reference from below tutorial when I implemented image capture and crop functionality.This will be helpful to you, I am sure. Let me know, if any issues.I would try to help further :)

http://code.tutsplus.com/tutorials/capture-and-crop-an-image-with-the-device-camera--mobile-11458