Search code examples
androidandroid-studioandroid-fragmentsandroid-cameraandroid-crop

Android: Cropping an image after capture or picking from Gallery


I am developing an application and as a part of that I need to crop an image after capture from camera or after picking it from gallery. I have a navigation drawer in my app and from which user can select an option to view his image (either camera or gallery). Whenever he clicks one of the options, a fragment will be called in which the rest is done (calling camera, clicking picture, getting the data and setting the image to the imageview). So, now I need to add the crop functionality for the image and I have used one of the cropping libraries available online which can be found here. Before trying it in my app, I have created a new android studio project and made a sample app in which the user can select camera by clicking a button and then cropping is done and the cropped image is set to the imageview on the screen. The project can be found here. Now, I tried to implement the same in my app but it doesn't work. Coming to the code, I have a navigation drawer class and then a fragment class. In my MainDrawerActivity (brief):

In the menu options:

if (id == R.id.nav_camera) { 
        Fragment_TouchImageView camFrag = (Fragment_TouchImageView) getSupportFragmentManager().findFragmentById(R.id.imageFragment);
        camFrag.startCamera();
    }
else if (id == R.id.nav_gallery) { 
        Fragment_TouchImageView galFrag = (Fragment_TouchImageView) getSupportFragmentManager().findFragmentById(R.id.imageFragment);
        galFrag.openGallery();
    }

Now, in my Fragment_TouchImageView.java (Fragment):

This is the entire code:

package com.example.shravan.watershed;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.soundcloud.android.crop.Crop;

import java.io.File;

public class Fragment_TouchImageView extends Fragment {

Uri imageUri;
private TouchImageView myTVF;
static final int REQUEST_IMAGE_CAPTURE = 10;
static final int PICK_IMAGE = 100;
private static Context context;
private static final String TAG = "Arunachala";

public Fragment_TouchImageView() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_fragment__touch_image_view, container, false);
    context= getActivity().getApplicationContext();
    myTVF = (TouchImageView) v.findViewById(R.id.img);
    myTVF.setImageBitmap(null);
    return v;
}

public void startCamera() {
    Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(i, REQUEST_IMAGE_CAPTURE);
}

public void openGallery() {
    Intent gallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
    startActivityForResult(gallery, PICK_IMAGE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
        print("Camera requested");
        beginCrop(data.getData());
        print("Crop called and came to next line");
    }
    else if (requestCode == PICK_IMAGE  && resultCode == Activity.RESULT_OK)           {
        print("Gallery requested");
        beginCrop(data.getData());
        print("Crop called and came to next line");
    }
    else if (requestCode == Crop.REQUEST_CROP) {
        print("Crop.REQUEST_CROP called");
        handleCrop(resultCode, data);
        print("handleCrop called and came to next line");
    }
}

private void beginCrop(Uri source) {
    print("Crop has begun");
    Uri destination = Uri.fromFile(new File(context.getCacheDir(), "cropped"));
    Crop.of(source, destination).asSquare().start(getActivity());
    print("Crop has ended");
}

private void handleCrop(int resultCode, Intent result) {
    print("Came to handleCrop");
    if (resultCode == Activity.RESULT_OK) {
        print("RESULT OK");
        myTVF.setImageURI(Crop.getOutput(result));
    } else if (resultCode == Crop.RESULT_ERROR) {
        Toast.makeText(getActivity(), Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
    }
}

private void print(String s){
    Log.d(TAG, s);
}
}

So, I have given a series of Log tags to know the flow and here's the problem. Whenever I select the camera or gallery, it opens correctly and when I capture the image, beginCrop() is being called and when I select the required crop area and click Done., it does nothing. The flow is not going into this loop:

else if (requestCode == Crop.REQUEST_CROP) {
        print("Crop.REQUEST_CROP called");
        handleCrop(resultCode, data);
        print("handleCrop called and came to next line");
    }

The same works in a different sample application project without any problem.(It didn't have fragments)

Please help me figure this out!


Solution

  • I get the same problem few weeks ago when using the same Library so the problem is with onActivityResult and its requestCode when using it in fragment so try to call Crop.of this way:

    Crop.of(cropInputUri, cropOutputUri).asSquare().start(getContext(), Fragment.this, Crop.REQUEST_CROP);