Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support circle crop as an aspect ratio option #747

Open
wants to merge 1 commit into
base: master-non-native
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions ucrop/src/main/java/com/yalantis/ucrop/UCrop.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class UCrop {
public static final String EXTRA_INPUT_URI = EXTRA_PREFIX + ".InputUri";
public static final String EXTRA_OUTPUT_URI = EXTRA_PREFIX + ".OutputUri";
public static final String EXTRA_OUTPUT_CROP_ASPECT_RATIO = EXTRA_PREFIX + ".CropAspectRatio";
public static final String EXTRA_OUTPUT_CIRCLE_CROP = EXTRA_PREFIX + ".CircleCrop";
public static final String EXTRA_OUTPUT_IMAGE_WIDTH = EXTRA_PREFIX + ".ImageWidth";
public static final String EXTRA_OUTPUT_IMAGE_HEIGHT = EXTRA_PREFIX + ".ImageHeight";
public static final String EXTRA_OUTPUT_OFFSET_X = EXTRA_PREFIX + ".OffsetX";
Expand Down Expand Up @@ -220,6 +221,16 @@ public static float getOutputCropAspectRatio(@NonNull Intent intent) {
return intent.getFloatExtra(EXTRA_OUTPUT_CROP_ASPECT_RATIO, 0f);
}

/**
* Retrieve if image is circle cropped from the result Intent
*
* @param intent crop result intent
* @return circle crop flag
*/
public static boolean getOutputCircleCrop(@NonNull Intent intent) {
return intent.getBooleanExtra(EXTRA_OUTPUT_CIRCLE_CROP, false);
}

/**
* Method retrieves error from the result intent.
*
Expand Down
21 changes: 14 additions & 7 deletions ucrop/src/main/java/com/yalantis/ucrop/UCropActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ public class UCropActivity extends AppCompatActivity {
private boolean mShowBottomControls;
private boolean mShowLoader = true;

private UCropView mUCropView;
private GestureCropImageView mGestureCropImageView;
private OverlayView mOverlayView;
protected UCropView mUCropView;
protected GestureCropImageView mGestureCropImageView;
protected OverlayView mOverlayView;
private ViewGroup mWrapperStateAspectRatio, mWrapperStateRotate, mWrapperStateScale;
private ViewGroup mLayoutAspectRatio, mLayoutRotate, mLayoutScale;
private List<ViewGroup> mCropAspectRatioViews = new ArrayList<>();
Expand Down Expand Up @@ -269,6 +269,7 @@ private void processOptions(@NonNull Intent intent) {
} else if (aspectRatioList != null && aspectRationSelectedByDefault < aspectRatioList.size()) {
mGestureCropImageView.setTargetAspectRatio(aspectRatioList.get(aspectRationSelectedByDefault).getAspectRatioX() /
aspectRatioList.get(aspectRationSelectedByDefault).getAspectRatioY());
setCircleCrop(aspectRatioList.get(aspectRationSelectedByDefault).isCircle());
} else {
mGestureCropImageView.setTargetAspectRatio(CropImageView.SOURCE_IMAGE_ASPECT_RATIO);
}
Expand All @@ -283,6 +284,10 @@ private void processOptions(@NonNull Intent intent) {
}
}

protected void setCircleCrop(boolean circleCrop) {
mGestureCropImageView.setCircleCrop(circleCrop);
}

private void setupViews(@NonNull Intent intent) {
mStatusBarColor = intent.getIntExtra(UCrop.Options.EXTRA_STATUS_BAR_COLOR, ContextCompat.getColor(this, R.color.ucrop_color_statusbar));
mToolbarColor = intent.getIntExtra(UCrop.Options.EXTRA_TOOL_BAR_COLOR, ContextCompat.getColor(this, R.color.ucrop_color_toolbar));
Expand Down Expand Up @@ -470,9 +475,10 @@ private void setupAspectRatioWidget(@NonNull Intent intent) {
cropAspectRatioView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mGestureCropImageView.setTargetAspectRatio(
((AspectRatioTextView) ((ViewGroup) v).getChildAt(0)).getAspectRatio(v.isSelected()));
AspectRatioTextView ratioTextView = ((AspectRatioTextView) ((ViewGroup) v).getChildAt(0));
mGestureCropImageView.setTargetAspectRatio(ratioTextView.getAspectRatio(v.isSelected()));
mGestureCropImageView.setImageToWrapCropBounds();
setCircleCrop(ratioTextView.isCircle());
if (!v.isSelected()) {
for (ViewGroup cropAspectRatioView : mCropAspectRatioViews) {
cropAspectRatioView.setSelected(cropAspectRatioView == v);
Expand Down Expand Up @@ -669,7 +675,7 @@ protected void cropAndSaveImage() {

@Override
public void onBitmapCropped(@NonNull Uri resultUri, int offsetX, int offsetY, int imageWidth, int imageHeight) {
setResultUri(resultUri, mGestureCropImageView.getTargetAspectRatio(), offsetX, offsetY, imageWidth, imageHeight);
setResultUri(resultUri, mGestureCropImageView.getTargetAspectRatio(), mGestureCropImageView.isCircleCrop(), offsetX, offsetY, imageWidth, imageHeight);
finish();
}

Expand All @@ -681,10 +687,11 @@ public void onCropFailure(@NonNull Throwable t) {
});
}

protected void setResultUri(Uri uri, float resultAspectRatio, int offsetX, int offsetY, int imageWidth, int imageHeight) {
protected void setResultUri(Uri uri, float resultAspectRatio, boolean circleCrop, int offsetX, int offsetY, int imageWidth, int imageHeight) {
setResult(RESULT_OK, new Intent()
.putExtra(UCrop.EXTRA_OUTPUT_URI, uri)
.putExtra(UCrop.EXTRA_OUTPUT_CROP_ASPECT_RATIO, resultAspectRatio)
.putExtra(UCrop.EXTRA_OUTPUT_CIRCLE_CROP, circleCrop)
.putExtra(UCrop.EXTRA_OUTPUT_IMAGE_WIDTH, imageWidth)
.putExtra(UCrop.EXTRA_OUTPUT_IMAGE_HEIGHT, imageHeight)
.putExtra(UCrop.EXTRA_OUTPUT_OFFSET_X, offsetX)
Expand Down
21 changes: 14 additions & 7 deletions ucrop/src/main/java/com/yalantis/ucrop/UCropFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ public class UCropFragment extends Fragment {

private Transition mControlsTransition;

private UCropView mUCropView;
private GestureCropImageView mGestureCropImageView;
private OverlayView mOverlayView;
protected UCropView mUCropView;
protected GestureCropImageView mGestureCropImageView;
protected OverlayView mOverlayView;
private ViewGroup mWrapperStateAspectRatio, mWrapperStateRotate, mWrapperStateScale;
private ViewGroup mLayoutAspectRatio, mLayoutRotate, mLayoutScale;
private List<ViewGroup> mCropAspectRatioViews = new ArrayList<>();
Expand Down Expand Up @@ -250,6 +250,7 @@ private void processOptions(@NonNull Bundle bundle) {
} else if (aspectRatioList != null && aspectRationSelectedByDefault < aspectRatioList.size()) {
mGestureCropImageView.setTargetAspectRatio(aspectRatioList.get(aspectRationSelectedByDefault).getAspectRatioX() /
aspectRatioList.get(aspectRationSelectedByDefault).getAspectRatioY());
setCircleCrop(aspectRatioList.get(aspectRationSelectedByDefault).isCircle());
} else {
mGestureCropImageView.setTargetAspectRatio(CropImageView.SOURCE_IMAGE_ASPECT_RATIO);
}
Expand All @@ -264,6 +265,10 @@ private void processOptions(@NonNull Bundle bundle) {
}
}

protected void setCircleCrop(boolean circleCrop) {
mGestureCropImageView.setCircleCrop(circleCrop);
}

private void initiateRootViews(View view) {
mUCropView = view.findViewById(R.id.ucrop);
mGestureCropImageView = mUCropView.getCropImageView();
Expand Down Expand Up @@ -353,9 +358,10 @@ private void setupAspectRatioWidget(@NonNull Bundle bundle, View view) {
cropAspectRatioView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mGestureCropImageView.setTargetAspectRatio(
((AspectRatioTextView) ((ViewGroup) v).getChildAt(0)).getAspectRatio(v.isSelected()));
AspectRatioTextView ratioTextView = ((AspectRatioTextView) ((ViewGroup) v).getChildAt(0));
mGestureCropImageView.setTargetAspectRatio(ratioTextView.getAspectRatio(v.isSelected()));
mGestureCropImageView.setImageToWrapCropBounds();
setCircleCrop(ratioTextView.isCircle());
if (!v.isSelected()) {
for (ViewGroup cropAspectRatioView : mCropAspectRatioViews) {
cropAspectRatioView.setSelected(cropAspectRatioView == v);
Expand Down Expand Up @@ -550,7 +556,7 @@ public void cropAndSaveImage() {

@Override
public void onBitmapCropped(@NonNull Uri resultUri, int offsetX, int offsetY, int imageWidth, int imageHeight) {
callback.onCropFinish(getResult(resultUri, mGestureCropImageView.getTargetAspectRatio(), offsetX, offsetY, imageWidth, imageHeight));
callback.onCropFinish(getResult(resultUri, mGestureCropImageView.getTargetAspectRatio(), mGestureCropImageView.isCircleCrop(), offsetX, offsetY, imageWidth, imageHeight));
callback.loadingProgress(false);
}

Expand All @@ -561,10 +567,11 @@ public void onCropFailure(@NonNull Throwable t) {
});
}

protected UCropResult getResult(Uri uri, float resultAspectRatio, int offsetX, int offsetY, int imageWidth, int imageHeight) {
protected UCropResult getResult(Uri uri, float resultAspectRatio, boolean circleCrop, int offsetX, int offsetY, int imageWidth, int imageHeight) {
return new UCropResult(RESULT_OK, new Intent()
.putExtra(UCrop.EXTRA_OUTPUT_URI, uri)
.putExtra(UCrop.EXTRA_OUTPUT_CROP_ASPECT_RATIO, resultAspectRatio)
.putExtra(UCrop.EXTRA_OUTPUT_CIRCLE_CROP, circleCrop)
.putExtra(UCrop.EXTRA_OUTPUT_IMAGE_WIDTH, imageWidth)
.putExtra(UCrop.EXTRA_OUTPUT_IMAGE_HEIGHT, imageHeight)
.putExtra(UCrop.EXTRA_OUTPUT_OFFSET_X, offsetX)
Expand Down
11 changes: 11 additions & 0 deletions ucrop/src/main/java/com/yalantis/ucrop/model/AspectRatio.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,32 @@ public class AspectRatio implements Parcelable {
private final String mAspectRatioTitle;
private final float mAspectRatioX;
private final float mAspectRatioY;
private final boolean mCircle;

public AspectRatio(@Nullable String aspectRatioTitle, float aspectRatioX, float aspectRatioY) {
this(aspectRatioTitle, aspectRatioX, aspectRatioY, false);
}

public AspectRatio(@Nullable String aspectRatioTitle, float aspectRatioX, float aspectRatioY, boolean circle) {
mAspectRatioTitle = aspectRatioTitle;
mAspectRatioX = aspectRatioX;
mAspectRatioY = aspectRatioY;
mCircle = circle;
}

protected AspectRatio(Parcel in) {
mAspectRatioTitle = in.readString();
mAspectRatioX = in.readFloat();
mAspectRatioY = in.readFloat();
mCircle = in.readInt() != 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mAspectRatioTitle);
dest.writeFloat(mAspectRatioX);
dest.writeFloat(mAspectRatioY);
dest.writeInt(mCircle ? 1 : 0);
}

@Override
Expand Down Expand Up @@ -64,4 +72,7 @@ public float getAspectRatioY() {
return mAspectRatioY;
}

public boolean isCircle() {
return mCircle;
}
}
12 changes: 12 additions & 0 deletions ucrop/src/main/java/com/yalantis/ucrop/view/CropImageView.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class CropImageView extends TransformImageView {
private final Matrix mTempMatrix = new Matrix();

private float mTargetAspectRatio;
private boolean mCircleCrop;
private float mMaxScaleMultiplier = DEFAULT_MAX_SCALE_MULTIPLIER;

private CropBoundsChangeListener mCropBoundsChangeListener;
Expand Down Expand Up @@ -109,6 +110,13 @@ public float getTargetAspectRatio() {
return mTargetAspectRatio;
}

/**
* @return - whether circle crop is enabled or not
*/
public boolean isCircleCrop() {
return mCircleCrop;
}

/**
* Updates current crop rectangle with given. Also recalculates image properties and position
* to fit new crop rectangle.
Expand Down Expand Up @@ -148,6 +156,10 @@ public void setTargetAspectRatio(float targetAspectRatio) {
}
}

public void setCircleCrop(boolean circleCrop) {
mCircleCrop = circleCrop;
}

@Nullable
public CropBoundsChangeListener getCropBoundsChangeListener() {
return mCropBoundsChangeListener;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class AspectRatioTextView extends AppCompatTextView {

private String mAspectRatioTitle;
private float mAspectRatioX, mAspectRatioY;
private boolean mCircle;

public AspectRatioTextView(Context context) {
this(context, null);
Expand Down Expand Up @@ -71,6 +72,7 @@ public void setAspectRatio(@NonNull AspectRatio aspectRatio) {
mAspectRatioTitle = aspectRatio.getAspectRatioTitle();
mAspectRatioX = aspectRatio.getAspectRatioX();
mAspectRatioY = aspectRatio.getAspectRatioY();
mCircle = aspectRatio.isCircle();

if (mAspectRatioX == CropImageView.SOURCE_IMAGE_ASPECT_RATIO || mAspectRatioY == CropImageView.SOURCE_IMAGE_ASPECT_RATIO) {
mAspectRatio = CropImageView.SOURCE_IMAGE_ASPECT_RATIO;
Expand All @@ -89,6 +91,10 @@ public float getAspectRatio(boolean toggleRatio) {
return mAspectRatio;
}

public boolean isCircle() {
return mCircle;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Expand Down