Skip to content
This repository has been archived by the owner on Mar 17, 2023. It is now read-only.

Add configurable aspect ratios #66

Open
wants to merge 7 commits into
base: master
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ You can receive the new processed image path and it's edit status like this-
super.onActivityResult(requestCode, resultCode, data);

if (requestCode == PHOTO_EDITOR_REQUEST_CODE) { // same code you used while starting
String newFilePath = data.getStringExtra(EditImageActivity.OUTPUT_PATH);
String newFilePath = data.getStringExtra(ImageEditorIntentBuilder.OUTPUT_PATH);
boolean isImageEdit = data.getBooleanExtra(EditImageActivity.IMAGE_IS_EDIT, false);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
Expand All @@ -29,6 +30,8 @@

import org.jetbrains.annotations.NotNull;

import java.util.List;

import iamutkarshtiwari.github.io.ananas.BaseActivity;
import iamutkarshtiwari.github.io.ananas.R;
import iamutkarshtiwari.github.io.ananas.editimage.fragment.AddTextFragment;
Expand All @@ -39,6 +42,7 @@
import iamutkarshtiwari.github.io.ananas.editimage.fragment.RotateFragment;
import iamutkarshtiwari.github.io.ananas.editimage.fragment.SaturationFragment;
import iamutkarshtiwari.github.io.ananas.editimage.fragment.StickerFragment;
import iamutkarshtiwari.github.io.ananas.editimage.fragment.crop.AspectRatio;
import iamutkarshtiwari.github.io.ananas.editimage.fragment.crop.CropFragment;
import iamutkarshtiwari.github.io.ananas.editimage.fragment.paint.PaintFragment;
import iamutkarshtiwari.github.io.ananas.editimage.interfaces.OnLoadingDialogListener;
Expand Down Expand Up @@ -79,6 +83,7 @@ public class EditImageActivity extends BaseActivity implements OnLoadingDialogLi
Manifest.permission.WRITE_EXTERNAL_STORAGE
};

public Uri sourceUri;
public String sourceFilePath;
public String outputFilePath;
public String editorTitle;
Expand Down Expand Up @@ -115,8 +120,17 @@ public class EditImageActivity extends BaseActivity implements OnLoadingDialogLi
private OnMainBitmapChangeListener onMainBitmapChangeListener;
private CompositeDisposable compositeDisposable = new CompositeDisposable();

private List<AspectRatio> aspectRatios;
private float aspectRatioMin;
private String aspectRatioMinMsg;
private float aspectRatioMax;
private String aspectRatioMaxMsg;

public static void start(Activity activity, Intent intent, int requestCode) {
if (TextUtils.isEmpty(intent.getStringExtra(ImageEditorIntentBuilder.SOURCE_PATH))) {
String sourcePath = intent.getStringExtra(ImageEditorIntentBuilder.SOURCE_PATH);
String sourceUriStr = intent.getStringExtra(ImageEditorIntentBuilder.SOURCE_URI);

if (TextUtils.isEmpty(sourcePath) && TextUtils.isEmpty(sourceUriStr)) {
Toast.makeText(activity, R.string.iamutkarshtiwari_github_io_ananas_not_selected, Toast.LENGTH_SHORT).show();
return;
}
Expand Down Expand Up @@ -151,9 +165,20 @@ private void getData() {
isPortraitForced = getIntent().getBooleanExtra(ImageEditorIntentBuilder.FORCE_PORTRAIT, false);
isSupportActionBarEnabled = getIntent().getBooleanExtra(ImageEditorIntentBuilder.SUPPORT_ACTION_BAR_VISIBILITY, false);

String sourceUriStr = getIntent().getStringExtra(ImageEditorIntentBuilder.SOURCE_URI);
if (!TextUtils.isEmpty(sourceUriStr)) {
sourceUri = Uri.parse(sourceUriStr);
}

sourceFilePath = getIntent().getStringExtra(ImageEditorIntentBuilder.SOURCE_PATH);
outputFilePath = getIntent().getStringExtra(ImageEditorIntentBuilder.OUTPUT_PATH);
editorTitle = getIntent().getStringExtra(ImageEditorIntentBuilder.EDITOR_TITLE);

aspectRatios = (List<AspectRatio>) getIntent().getSerializableExtra(ImageEditorIntentBuilder.ASPECT_RATIOS);
aspectRatioMin = getIntent().getFloatExtra(ImageEditorIntentBuilder.ASPECT_RATIO_MIN, CropFragment.NO_ASPECT_RATIO_LIMIT);
aspectRatioMinMsg = getIntent().getStringExtra(ImageEditorIntentBuilder.ASPECT_RATIO_MIN_MSG);
aspectRatioMax = getIntent().getFloatExtra(ImageEditorIntentBuilder.ASPECT_RATIO_MAX, CropFragment.NO_ASPECT_RATIO_LIMIT);
aspectRatioMaxMsg = getIntent().getStringExtra(ImageEditorIntentBuilder.ASPECT_RATIO_MAX_MSG);
}

private void initView() {
Expand Down Expand Up @@ -205,7 +230,12 @@ private void initView() {
this.getSupportFragmentManager());
stickerFragment = StickerFragment.newInstance();
filterListFragment = FilterListFragment.newInstance();

cropFragment = CropFragment.newInstance();
cropFragment.setAspectRatios(aspectRatios);
cropFragment.setMinimumAspectRatio(aspectRatioMin, aspectRatioMinMsg);
cropFragment.setMaximumAspectRatio(aspectRatioMax, aspectRatioMaxMsg);

rotateFragment = RotateFragment.newInstance();
paintFragment = PaintFragment.newInstance();
beautyFragment = BeautyFragment.newInstance();
Expand All @@ -228,7 +258,11 @@ private void initView() {
ActivityCompat.requestPermissions(this, requiredPermissions, PERMISSIONS_REQUEST_CODE);
}

loadImageFromFile(sourceFilePath);
if (!TextUtils.isEmpty(sourceFilePath)) {
loadImageFromFile(sourceFilePath);
} else {
loadImageFromUri(sourceUri);
}
}

private void setOnMainBitmapChangeListener(OnMainBitmapChangeListener listener) {
Expand Down Expand Up @@ -337,6 +371,7 @@ public void changeMainBitmap(Bitmap newBit, boolean needPushUndoStack) {

protected void onSaveTaskDone() {
Intent returnIntent = new Intent();
returnIntent.putExtra(ImageEditorIntentBuilder.SOURCE_URI, sourceUri.toString());
returnIntent.putExtra(ImageEditorIntentBuilder.SOURCE_PATH, sourceFilePath);
returnIntent.putExtra(ImageEditorIntentBuilder.OUTPUT_PATH, outputFilePath);
returnIntent.putExtra(IS_IMAGE_EDITED, numberOfOperations > 0);
Expand All @@ -349,6 +384,20 @@ protected void doSaveImage() {
if (numberOfOperations <= 0)
return;

float aspectRatio = (float) mainBitmap.getWidth() / mainBitmap.getHeight();

if (aspectRatioMin != CropFragment.NO_ASPECT_RATIO_LIMIT &&
aspectRatio < aspectRatioMin) {
Toast.makeText(this, aspectRatioMinMsg, Toast.LENGTH_SHORT).show();
return;
}

if (aspectRatioMax != CropFragment.NO_ASPECT_RATIO_LIMIT &&
aspectRatio > aspectRatioMax) {
Toast.makeText(this, aspectRatioMaxMsg, Toast.LENGTH_SHORT).show();
return;
}

compositeDisposable.clear();

Disposable saveImageDisposable = saveImage(mainBitmap)
Expand Down Expand Up @@ -377,6 +426,19 @@ private Single<Boolean> saveImage(Bitmap finalBitmap) {
});
}

private void loadImageFromUri(Uri uri) {
compositeDisposable.clear();

Disposable loadImageDisposable = loadImage(uri)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(subscriber -> loadingDialog.show())
.doFinally(() -> loadingDialog.dismiss())
.subscribe(processedBitmap -> changeMainBitmap(processedBitmap, false), e -> showToast(R.string.iamutkarshtiwari_github_io_ananas_load_error));

compositeDisposable.add(loadImageDisposable);
}

private void loadImageFromFile(String filePath) {
compositeDisposable.clear();

Expand All @@ -395,6 +457,11 @@ private Single<Bitmap> loadImage(String filePath) {
imageHeight));
}

private Single<Bitmap> loadImage(Uri uri) {
return Single.fromCallable(() -> BitmapUtils.decodeSampledBitmap(this, uri,
imageWidth, imageHeight));
}

private void showToast(@StringRes int resId) {
Toast.makeText(this, resId, Toast.LENGTH_SHORT).show();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package iamutkarshtiwari.github.io.ananas.editimage

import android.content.Context
import android.content.Intent
import android.net.Uri
import iamutkarshtiwari.github.io.ananas.editimage.fragment.crop.AspectRatio

class ImageEditorIntentBuilder @JvmOverloads constructor(private val context: Context,
private val sourcePath: String?,
Expand All @@ -11,6 +13,17 @@ class ImageEditorIntentBuilder @JvmOverloads constructor(private val context: Co
EditImageActivity::class.java
)
) {
private var sourceUri: Uri? = null

@JvmOverloads constructor(context: Context,
sourceUri: Uri,
outputPath: String?,
intent: Intent = Intent(
context,
EditImageActivity::class.java
)) : this(context, null, outputPath, intent) {
this.sourceUri = sourceUri
}

fun withAddText(): ImageEditorIntentBuilder {
intent.putExtra(ADD_TEXT_FEATURE, true)
Expand Down Expand Up @@ -62,8 +75,16 @@ class ImageEditorIntentBuilder @JvmOverloads constructor(private val context: Co
return this
}

fun withSourceUri(sourceUri: Uri): ImageEditorIntentBuilder {
this.sourceUri = sourceUri
intent.putExtra(SOURCE_URI, sourceUri.toString())
intent.removeExtra(SOURCE_PATH)
return this
}

fun withSourcePath(sourcePath: String): ImageEditorIntentBuilder {
intent.putExtra(SOURCE_PATH, sourcePath)
intent.removeExtra(SOURCE_URI)
return this
}

Expand All @@ -72,6 +93,23 @@ class ImageEditorIntentBuilder @JvmOverloads constructor(private val context: Co
return this
}

fun withAspectRatios(aspectRatios: ArrayList<AspectRatio>): ImageEditorIntentBuilder {
intent.putExtra(ASPECT_RATIOS, aspectRatios)
return this
}

fun withMinimumAspectRatios(minimumAspectRatio: Float, validationMessage: String): ImageEditorIntentBuilder {
intent.putExtra(ASPECT_RATIO_MIN, minimumAspectRatio)
intent.putExtra(ASPECT_RATIO_MIN_MSG, validationMessage)
return this
}

fun withMaximumAspectRatios(maximumAspectRatio: Float, validationMessage: String): ImageEditorIntentBuilder {
intent.putExtra(ASPECT_RATIO_MAX, maximumAspectRatio)
intent.putExtra(ASPECT_RATIO_MAX_MSG, validationMessage)
return this
}

fun forcePortrait(isForcePortrait: Boolean): ImageEditorIntentBuilder {
intent.putExtra(FORCE_PORTRAIT, isForcePortrait)
return this
Expand All @@ -85,10 +123,14 @@ class ImageEditorIntentBuilder @JvmOverloads constructor(private val context: Co
@Throws(Exception::class)
fun build(): Intent {

if (sourcePath.isNullOrBlank()) {
throw Exception("Output image path required. Use withOutputPath(path) to provide the output image path.")
} else {
if (sourcePath.isNullOrBlank() && sourceUri == null) {
throw Exception("Source image required. Use withSourcePath(path) or withSourceUri(uri) to provide the source.")
} else if (!sourcePath.isNullOrBlank() && sourceUri != null) {
throw Exception("Multiple source images specified. Use either withSourcePath(path) or withSourceUri(uri) to provide the source.")
} else if (!sourcePath.isNullOrBlank()) {
intent.putExtra(SOURCE_PATH, sourcePath)
} else {
intent.putExtra(SOURCE_URI, sourceUri.toString())
}

if (outputPath.isNullOrBlank()) {
Expand All @@ -111,10 +153,17 @@ class ImageEditorIntentBuilder @JvmOverloads constructor(private val context: Co
const val BEAUTY_FEATURE = "beauty_feature"
const val STICKER_FEATURE = "sticker_feature"

const val SOURCE_URI = "source_uri"
const val SOURCE_PATH = "source_path"
const val OUTPUT_PATH = "output_path"
const val FORCE_PORTRAIT = "force_portrait"
const val EDITOR_TITLE = "editor_title"
const val SUPPORT_ACTION_BAR_VISIBILITY = "support_action_bar_visibility"

const val ASPECT_RATIOS = "aspect_ratios"
const val ASPECT_RATIO_MIN = "aspect_ratio_min"
const val ASPECT_RATIO_MIN_MSG = "aspect_ratio_min_msg"
const val ASPECT_RATIO_MAX = "aspect_ratio_max"
const val ASPECT_RATIO_MAX_MSG = "aspect_ratio_max_msg"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package iamutkarshtiwari.github.io.ananas.editimage.fragment.crop;

public class AspectRatio implements java.io.Serializable {
private final String name;
private final int x;
private final int y;

public AspectRatio(String name) {
this(name, 0, 0);
}

public AspectRatio(String name, int x, int y) {
this.name = name;
this.x = x;
this.y = y;
}

public String getName() {
return name;
}

public int getX() {
return x;
}

public int getY() {
return y;
}

public boolean isFree() {
return x == 0 && y == 0;
}

public boolean isFitImage() {
return x == -1 && y == -1;
}
}
Loading