diff --git a/README.md b/README.md index e35f1f0..f8fdfa7 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,14 @@ -![](https://raw.github.com/wiki/IsseiAoki/SimpleCropView/images/device-art/cover-art.png) +Fork of SimpleCropView https://github.com/IsseiAoki/SimpleCropView + +[![](https://jitpack.io/v/ZacWolf/SimpleCropView.svg)](https://jitpack.io/#ZacWolf/SimpleCropView) -#SimpleCropView -[![build status](https://travis-ci.org/IsseiAoki/SimpleCropView.svg)](https://travis-ci.org/IsseiAoki/SimpleCropView) -[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-SimpleCropView-green.svg?style=flat)](https://android-arsenal.com/details/1/2366) -[![Android Gems](http://www.android-gems.com/badge/IsseiAoki/SimpleCropView.svg?branch=master)](http://www.android-gems.com/lib/IsseiAoki/SimpleCropView) +![](https://raw.github.com/wiki/IsseiAoki/SimpleCropView/images/device-art/cover-art.png) The SimpleCropView is an image cropping library for Android.
It simplifies your code for cropping image and provides an easily customizable UI.

Supported on API Level 10 and above. -![demo](https://raw.github.com/wiki/IsseiAoki/SimpleCropView/images/1.1.0/demo_basic_usage.gif) - - ##Table of Contents * [Download](#download) * [Example](#example) diff --git a/build.gradle b/build.gradle index da96688..c60b8a7 100644 --- a/build.gradle +++ b/build.gradle @@ -3,11 +3,12 @@ buildscript { repositories { jcenter() + maven { url "https://jitpack.io" } } dependencies { - classpath 'com.android.tools.build:gradle:2.0.0' + classpath 'com.android.tools.build:gradle:2.2.2' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6' - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -17,5 +18,10 @@ buildscript { allprojects { repositories { jcenter() + maven { url "https://jitpack.io" } } } + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0ecc9c0..1081cc3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/simplecropview-sample/build.gradle b/simplecropview-sample/build.gradle index c1dd61e..076e051 100644 --- a/simplecropview-sample/build.gradle +++ b/simplecropview-sample/build.gradle @@ -2,13 +2,13 @@ apply plugin: 'com.android.application' apply plugin: 'android-apt' android { - compileSdkVersion 23 - buildToolsVersion "23.0.2" + compileSdkVersion 25 + buildToolsVersion "25.0.0" defaultConfig { applicationId "com.example.simplecropviewsample" minSdkVersion 13 - targetSdkVersion 23 + targetSdkVersion 24 versionCode 1 versionName "1.0.0" } @@ -38,7 +38,7 @@ ext { } dependencies { - compile "com.android.support:appcompat-v7:23.3.0" + compile "com.android.support:appcompat-v7:25+" compile fileTree(dir: 'libs', include: ['*.jar']) compile project(':simplecropview') compile "com.github.hotchemi:permissionsdispatcher:${permissionsDispatcherVersion}" diff --git a/simplecropview-sample/src/main/java/com/example/simplecropviewsample/MainFragment.java b/simplecropview-sample/src/main/java/com/example/simplecropviewsample/MainFragment.java index 9d5ce5b..02763d9 100644 --- a/simplecropview-sample/src/main/java/com/example/simplecropviewsample/MainFragment.java +++ b/simplecropview-sample/src/main/java/com/example/simplecropviewsample/MainFragment.java @@ -1,11 +1,4 @@ package com.example.simplecropviewsample; - -import com.isseiaoki.simplecropview.CropImageView; -import com.isseiaoki.simplecropview.callback.CropCallback; -import com.isseiaoki.simplecropview.callback.LoadCallback; -import com.isseiaoki.simplecropview.callback.SaveCallback; -import com.isseiaoki.simplecropview.util.Utils; - import android.Manifest; import android.app.Activity; import android.content.DialogInterface; @@ -21,8 +14,15 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import android.widget.LinearLayout; +import com.isseiaoki.simplecropview.CropImageView; +import com.isseiaoki.simplecropview.callback.CropCallback; +import com.isseiaoki.simplecropview.callback.LoadCallback; +import com.isseiaoki.simplecropview.callback.SaveCallback; +import com.isseiaoki.simplecropview.util.Utils; + import java.io.File; import permissions.dispatcher.NeedsPermission; @@ -38,6 +38,7 @@ public class MainFragment extends Fragment { // Views /////////////////////////////////////////////////////////////////////////////////////// private CropImageView mCropView; + private ImageView mPreView; private LinearLayout mRootLayout; // Note: only the system can call this constructor by reflection. @@ -71,9 +72,6 @@ public void onViewCreated(View view, Bundle savedInstanceState) { FontUtils.setFont(mRootLayout); // mCropView.setDebug(true); // set bitmap to CropImageView - if (mCropView.getImageBitmap() == null) { - mCropView.setImageResource(R.drawable.sample5); - } } @Override @@ -81,10 +79,10 @@ public void onActivityResult(int requestCode, int resultCode, Intent result) { super.onActivityResult(requestCode, resultCode, result); if (requestCode == REQUEST_PICK_IMAGE && resultCode == Activity.RESULT_OK) { showProgress(); - mCropView.startLoad(result.getData(), mLoadCallback); + mCropView.startLoad(result.getData(), mLoadCallback,mPreView); } else if (requestCode == REQUEST_SAF_PICK_IMAGE && resultCode == Activity.RESULT_OK) { showProgress(); - mCropView.startLoad(Utils.ensureUriPermission(getContext(), result), mLoadCallback); + mCropView.startLoad(Utils.ensureUriPermission(getContext(), result), mLoadCallback,mPreView); } } @@ -98,6 +96,8 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis private void bindViews(View view) { mCropView = (CropImageView) view.findViewById(R.id.cropImageView); + mPreView = (ImageView) view.findViewById(R.id.previewImageView); + view.findViewById(R.id.buttonDone).setOnClickListener(btnListener); view.findViewById(R.id.buttonFitImage).setOnClickListener(btnListener); view.findViewById(R.id.button1_1).setOnClickListener(btnListener); @@ -245,7 +245,7 @@ public void onSuccess() { } @Override - public void onError() { + public void onError(Throwable e) { dismissProgress(); } }; @@ -256,7 +256,7 @@ public void onSuccess(Bitmap cropped) { } @Override - public void onError() { + public void onError(Throwable e) { } }; @@ -268,8 +268,8 @@ public void onSuccess(Uri outputUri) { } @Override - public void onError() { + public void onError(Throwable e) { dismissProgress(); } }; -} \ No newline at end of file +} diff --git a/simplecropview-sample/src/main/res/drawable/border_black_fill_trans.xml b/simplecropview-sample/src/main/res/drawable/border_black_fill_trans.xml new file mode 100644 index 0000000..c76bfd5 --- /dev/null +++ b/simplecropview-sample/src/main/res/drawable/border_black_fill_trans.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/simplecropview-sample/src/main/res/drawable/border_black_fill_white.xml b/simplecropview-sample/src/main/res/drawable/border_black_fill_white.xml new file mode 100644 index 0000000..6eb4e5b --- /dev/null +++ b/simplecropview-sample/src/main/res/drawable/border_black_fill_white.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/simplecropview-sample/src/main/res/layout/fragment_main.xml b/simplecropview-sample/src/main/res/layout/fragment_main.xml index 9b06019..5754504 100644 --- a/simplecropview-sample/src/main/res/layout/fragment_main.xml +++ b/simplecropview-sample/src/main/res/layout/fragment_main.xml @@ -48,6 +48,35 @@ custom:scv_guide_stroke_weight="1dp" /> + + + + + + + + - \ No newline at end of file + diff --git a/simplecropview-sample/src/main/res/values/colors.xml b/simplecropview-sample/src/main/res/values/colors.xml index 9dc18a7..c68c2cc 100644 --- a/simplecropview-sample/src/main/res/values/colors.xml +++ b/simplecropview-sample/src/main/res/values/colors.xml @@ -9,4 +9,7 @@ #1C1C1C #AA1C1C1C #333333 - \ No newline at end of file + + #000000 + #FFFFFF + diff --git a/simplecropview/build.gradle b/simplecropview/build.gradle index b5433a5..cc7e543 100644 --- a/simplecropview/build.gradle +++ b/simplecropview/build.gradle @@ -1,9 +1,8 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 23 - buildToolsVersion "23.0.2" - + compileSdkVersion 25 + buildToolsVersion "25.0.0" defaultConfig { minSdkVersion 10 targetSdkVersion 23 diff --git a/simplecropview/src/main/java/com/isseiaoki/simplecropview/CropImageView.java b/simplecropview/src/main/java/com/isseiaoki/simplecropview/CropImageView.java index e34561e..d618b35 100644 --- a/simplecropview/src/main/java/com/isseiaoki/simplecropview/CropImageView.java +++ b/simplecropview/src/main/java/com/isseiaoki/simplecropview/CropImageView.java @@ -1,16 +1,4 @@ package com.isseiaoki.simplecropview; - -import com.isseiaoki.simplecropview.animation.SimpleValueAnimator; -import com.isseiaoki.simplecropview.animation.SimpleValueAnimatorListener; -import com.isseiaoki.simplecropview.animation.ValueAnimatorV14; -import com.isseiaoki.simplecropview.animation.ValueAnimatorV8; -import com.isseiaoki.simplecropview.callback.Callback; -import com.isseiaoki.simplecropview.callback.CropCallback; -import com.isseiaoki.simplecropview.callback.LoadCallback; -import com.isseiaoki.simplecropview.callback.SaveCallback; -import com.isseiaoki.simplecropview.util.Logger; -import com.isseiaoki.simplecropview.util.Utils; - import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; @@ -41,6 +29,17 @@ import android.view.animation.Interpolator; import android.widget.ImageView; +import com.isseiaoki.simplecropview.animation.SimpleValueAnimator; +import com.isseiaoki.simplecropview.animation.SimpleValueAnimatorListener; +import com.isseiaoki.simplecropview.animation.ValueAnimatorV14; +import com.isseiaoki.simplecropview.animation.ValueAnimatorV8; +import com.isseiaoki.simplecropview.callback.Callback; +import com.isseiaoki.simplecropview.callback.CropCallback; +import com.isseiaoki.simplecropview.callback.LoadCallback; +import com.isseiaoki.simplecropview.callback.SaveCallback; +import com.isseiaoki.simplecropview.util.Logger; +import com.isseiaoki.simplecropview.util.Utils; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -111,6 +110,7 @@ public class CropImageView extends ImageView { private int mOutputImageWidth = 0; private int mOutputImageHeight = 0; private boolean mIsLoading = false; + private ImageView mPreviewImageView = null; // Instance variables for customizable attributes ////////////////////////////////////////////// private TouchArea mTouchArea = TouchArea.OUT_OF_BOUNDS; @@ -284,7 +284,8 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { - if (getDrawable() != null) setupLayout(mViewWidth, mViewHeight); + if (getDrawable() != null && !mIsInitialized) + setupLayout(mViewWidth, mViewHeight); } @Override @@ -302,6 +303,7 @@ public void onDraw(Canvas canvas) { if (mIsDebug) { drawDebugInfo(canvas); } + } } @@ -544,6 +546,7 @@ private void setupLayout(int viewW, int viewH) { mFrameRect = calcFrameRect(mImageRect); mIsInitialized = true; invalidate(); + int s=1; } private float calcScale(int viewW, int viewH, float angle) { @@ -671,6 +674,8 @@ private void onUp(MotionEvent e) { if (mHandleShowMode == ShowMode.SHOW_ON_TOUCH) mShowHandle = false; mTouchArea = TouchArea.OUT_OF_BOUNDS; invalidate(); + updatePreview(); + } private void onCancel() { @@ -1043,6 +1048,7 @@ public void onAnimationUpdated(float scale) { @Override public void onAnimationFinished() { mFrameRect = newRect; + updatePreview(); invalidate(); mIsAnimating = false; } @@ -1168,15 +1174,15 @@ private float constrain(float val, float min, float max, float defaultVal) { return val; } - private void postErrorOnMainThread(final Callback callback) { + private void postErrorOnMainThread(final Callback callback,final Throwable exception) { if (callback == null) return; if (Looper.myLooper() == Looper.getMainLooper()) { - callback.onError(); + callback.onError(exception); } else { mHandler.post(new Runnable() { @Override public void run() { - callback.onError(); + callback.onError(exception); } }); } @@ -1334,8 +1340,9 @@ private void saveToFile(Bitmap bitmap, final Uri uri) { bitmap.compress(mCompressFormat, mCompressQuality, outputStream); } } catch (IOException e) { - Logger.e("An error occurred while saving the image: " + uri, e); - postErrorOnMainThread(mSaveCallback); + final String msg = "An error occurred while saving the image: " + uri; + Logger.e(msg, e); + postErrorOnMainThread(mSaveCallback,new IOException(msg,e)); } finally { Utils.closeQuietly(outputStream); } @@ -1408,7 +1415,7 @@ public void setImageURI(Uri uri) { private void updateLayout() { resetImageInfo(); Drawable d = getDrawable(); - if (d != null) { + if (d != null && !mIsInitialized) { setupLayout(mViewWidth, mViewHeight); } } @@ -1430,11 +1437,24 @@ private void resetImageInfo() { * @param sourceUri Image Uri * @param callback Callback */ - public void startLoad(Uri sourceUri, LoadCallback callback) { + public void startLoad(Uri sourceUri, LoadCallback callback){ + startLoad(sourceUri,callback,null); + } + + /** + * Load image from Uri. + * + * @param sourceUri Image Uri + * @param callback Callback + * @param preview ImageView to be populated with the cropped area on event onUp + */ + public void startLoad(Uri sourceUri, LoadCallback callback, ImageView preview) { mLoadCallback = callback; mSourceUri = sourceUri; + mPreviewImageView = preview; + mPreviewImageView.setScaleType(ScaleType.FIT_XY); if (sourceUri == null) { - postErrorOnMainThread(mLoadCallback); + postErrorOnMainThread(mLoadCallback,new IllegalStateException("Source Uri must not be null.")); throw new IllegalStateException("Source Uri must not be null."); } mExecutor.submit(new Runnable() { @@ -1456,23 +1476,43 @@ public void run() { public void run() { mAngle = mExifRotation; setImageBitmap(sampledBitmap); + updatePreview(); if (mLoadCallback != null) mLoadCallback.onSuccess(); mIsLoading = false; } }); } catch (OutOfMemoryError e) { - Logger.e("OOM Error: " + e.getMessage(), e); - postErrorOnMainThread(mLoadCallback); + final String msg = "Oot of Memory Error: " + e.getMessage(); + Logger.e(msg, e); + postErrorOnMainThread(mLoadCallback,new OutOfMemoryError(msg)); mIsLoading = false; } catch (Exception e) { - Logger.e("An unexpected error has occurred: " + e.getMessage(), e); - postErrorOnMainThread(mLoadCallback); + final String msg = "An unexpected error has occurred: " + e.getMessage(); + Logger.e(msg, e); + postErrorOnMainThread(mLoadCallback,new Exception(msg,e)); mIsLoading = false; } } }); } + private void updatePreview(){ + mHandler.post(new Runnable(){ + @Override public void run(){ + float h=mPreviewImageView.getHeight(); + float w=mPreviewImageView.getWidth(); + float hr=getRatioY(h); + float wr=getRatioX(w); + try{ + mPreviewImageView.getLayoutParams().width=Math.round(h*(wr/hr)); + mPreviewImageView.setImageBitmap(getCroppedBitmap()); + }catch(Exception e){ + e.printStackTrace(); + } + } + } + ); + } /** * Rotate image * @@ -1510,6 +1550,7 @@ public void onAnimationFinished() { mAngle = newAngle % 360; mScale = newScale; setupLayout(mViewWidth, mViewHeight); + updatePreview(); mIsRotating = false; } }); @@ -1561,6 +1602,7 @@ public Bitmap getCroppedBitmap() { } cropped = circle; } + //mIsInitialized=false; return cropped; } @@ -1603,8 +1645,9 @@ public void startCrop(Uri saveUri, CropCallback cropCallback, SaveCallback saveC mCropCallback = cropCallback; mSaveCallback = saveCallback; if (mIsCropping) { - postErrorOnMainThread(mCropCallback); - postErrorOnMainThread(mSaveCallback); + final String msg = "Another cropping operation is already active."; + postErrorOnMainThread(mCropCallback,new RuntimeException(msg)); + postErrorOnMainThread(mSaveCallback,new RuntimeException(msg)); return; } mIsCropping = true; @@ -1645,11 +1688,11 @@ public void run() { } // Error else { - postErrorOnMainThread(mCropCallback); + postErrorOnMainThread(mCropCallback,new NullPointerException("Resulting crop generated a null value")); } if (mSaveUri == null) { - postErrorOnMainThread(mSaveCallback); + postErrorOnMainThread(mSaveCallback,new NullPointerException("The save location for the crop was null or invalid")); return; } saveToFile(cropped, mSaveUri); diff --git a/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/Callback.java b/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/Callback.java index 11fe903..f6e9340 100644 --- a/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/Callback.java +++ b/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/Callback.java @@ -1,5 +1,5 @@ package com.isseiaoki.simplecropview.callback; public interface Callback { - void onError(); + void onError(Throwable e); } diff --git a/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/CropCallback.java b/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/CropCallback.java index c49da34..d169190 100644 --- a/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/CropCallback.java +++ b/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/CropCallback.java @@ -4,5 +4,4 @@ public interface CropCallback extends Callback { void onSuccess(Bitmap cropped); - void onError(); } diff --git a/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/LoadCallback.java b/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/LoadCallback.java index 39cdd93..858d475 100644 --- a/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/LoadCallback.java +++ b/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/LoadCallback.java @@ -3,5 +3,4 @@ public interface LoadCallback extends Callback{ void onSuccess(); - void onError(); } diff --git a/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/SaveCallback.java b/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/SaveCallback.java index 11ffa33..0d727ec 100644 --- a/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/SaveCallback.java +++ b/simplecropview/src/main/java/com/isseiaoki/simplecropview/callback/SaveCallback.java @@ -5,5 +5,4 @@ public interface SaveCallback extends Callback{ void onSuccess(Uri outputUri); - void onError(); }