@@ -0,0 +1,1569 @@
import android .content .Context ;
import android .content .res .TypedArray ;
import android .graphics .Bitmap ;
import android .graphics .Canvas ;
import android .graphics .Matrix ;
import android .graphics .Paint ;
import android .graphics .Path ;
import android .graphics .PointF ;
import android .graphics .PorterDuff ;
import android .graphics .PorterDuffXfermode ;
import android .graphics .Rect ;
import android .graphics .RectF ;
import android .graphics .drawable .BitmapDrawable ;
import android .graphics .drawable .Drawable ;
import android .net .Uri ;
import android .os .Environment ;
import android .os .Parcel ;
import android .os .Parcelable ;
import android .util .AttributeSet ;
import android .util .DisplayMetrics ;
import android .view .MotionEvent ;
import android .view .WindowManager ;
import android .widget .ImageView ;
import com .goparties .gpuser .R ;
import java .io .File ;
import java .io .FileOutputStream ;
import java .io .IOException ;
public class CropImageView extends ImageView {
private static final String TAG = CropImageView .class .getSimpleName ();
// Constants ///////////////////////////////////////////////////////////////////////////////////
private static final int HANDLE_SIZE_IN_DP = 16 ;
private static final int MIN_FRAME_SIZE_IN_DP = 50 ;
private static final int FRAME_STROKE_WEIGHT_IN_DP = 1 ;
private static final int GUIDE_STROKE_WEIGHT_IN_DP = 1 ;
private static final float DEFAULT_INITIAL_FRAME_SCALE = 0.75f ;
private final int TRANSPARENT ;
private final int TRANSLUCENT_WHITE = 0xBBFFFFFF ;
private final int WHITE = 0xFFFFFFFF ;
private final int TRANSLUCENT_BLACK = 0xBB000000 ;
// Member variables ////////////////////////////////////////////////////////////////////////////
private int mViewWidth = 0 ;
private int mViewHeight = 0 ;
private float mScale = 1.0f ;
private float mAngle = 0.0f ;
private float mImgWidth = 0.0f ;
private float mImgHeight = 0.0f ;
private boolean mIsInitialized = false ;
private Matrix mMatrix = null ;
private Paint mPaintTransparent ;
private Paint mPaintFrame ;
private Paint mPaintBitmap ;
private RectF mFrameRect ;
private RectF mImageRect ;
private PointF mCenter = new PointF ();
private float mLastX , mLastY ;
// Instance variables for customizable attributes //////////////////////////////////////////////
private TouchArea mTouchArea = TouchArea .OUT_OF_BOUNDS ;
private CropMode mCropMode = CropMode .RATIO_1_1 ;
private ShowMode mGuideShowMode = ShowMode .SHOW_ALWAYS ;
private ShowMode mHandleShowMode = ShowMode .SHOW_ALWAYS ;
private float mMinFrameSize ;
private int mHandleSize ;
private int mTouchPadding = 0 ;
private boolean mShowGuide = true ;
private boolean mShowHandle = true ;
private boolean mIsCropEnabled = true ;
private boolean mIsEnabled = true ;
private PointF mCustomRatio = new PointF (1.0f , 1.0f );
private float mFrameStrokeWeight = 3.0f ;
private float mGuideStrokeWeight = 3.0f ;
private int mBackgroundColor ;
private int mOverlayColor ;
private int mFrameColor ;
private int mHandleColor ;
private int mGuideColor ;
private float mInitialFrameScale ; // 0.01 ~ 1.0, 0.75 is default value
private String imageName ;
// Constructor /////////////////////////////////////////////////////////////////////////////////
public CropImageView (Context context ) {
this (context , null );
}
public CropImageView (Context context , AttributeSet attrs ) {
this (context , attrs , 0 );
}
public CropImageView (Context context , AttributeSet attrs , int defStyle ) {
super (context , attrs , defStyle );
TRANSPARENT = getResources ().getColor (android .R .color .transparent );
float mDensity = getDensity ();
mHandleSize = (int ) (mDensity * HANDLE_SIZE_IN_DP );
mMinFrameSize = mDensity * MIN_FRAME_SIZE_IN_DP ;
mFrameStrokeWeight = mDensity * FRAME_STROKE_WEIGHT_IN_DP ;
mGuideStrokeWeight = mDensity * GUIDE_STROKE_WEIGHT_IN_DP ;
mPaintFrame = new Paint ();
mPaintTransparent = new Paint ();
mPaintBitmap = new Paint ();
mPaintBitmap .setFilterBitmap (true );
mMatrix = new Matrix ();
mScale = 1.0f ;
mBackgroundColor = TRANSPARENT ;
mFrameColor = WHITE ;
mOverlayColor = TRANSLUCENT_BLACK ;
mHandleColor = WHITE ;
mGuideColor = TRANSLUCENT_WHITE ;
// handle Styleable
handleStyleable (context , attrs , defStyle , mDensity );
}
// Lifecycle methods ///////////////////////////////////////////////////////////////////////////
@ Override
public Parcelable onSaveInstanceState () {
Parcelable superState = super .onSaveInstanceState ();
SavedState ss = new SavedState (superState );
Bitmap bm = getBitmap ();
ss .image = bm ;
ss .mode = this .mCropMode ;
ss .backgroundColor = this .mBackgroundColor ;
ss .overlayColor = this .mOverlayColor ;
ss .frameColor = this .mFrameColor ;
ss .guideShowMode = this .mGuideShowMode ;
ss .handleShowMode = this .mHandleShowMode ;
ss .showGuide = this .mShowGuide ;
ss .showHandle = this .mShowHandle ;
ss .handleSize = this .mHandleSize ;
ss .touchPadding = this .mTouchPadding ;
ss .minFrameSize = this .mMinFrameSize ;
ss .customRatioX = this .mCustomRatio .x ;
ss .customRatioY = this .mCustomRatio .y ;
ss .frameStrokeWeight = this .mFrameStrokeWeight ;
ss .guideStrokeWeight = this .mGuideStrokeWeight ;
ss .isCropEnabled = this .mIsCropEnabled ;
ss .handleColor = this .mHandleColor ;
ss .guideColor = this .mGuideColor ;
ss .initialFrameScale = this .mInitialFrameScale ;
return ss ;
}
@ Override
public void onRestoreInstanceState (Parcelable state ) {
SavedState ss = (SavedState ) state ;
super .onRestoreInstanceState (ss .getSuperState ());
this .mCropMode = ss .mode ;
this .mBackgroundColor = ss .backgroundColor ;
this .mOverlayColor = ss .overlayColor ;
this .mFrameColor = ss .frameColor ;
this .mGuideShowMode = ss .guideShowMode ;
this .mHandleShowMode = ss .handleShowMode ;
this .mShowGuide = ss .showGuide ;
this .mShowHandle = ss .showHandle ;
this .mHandleSize = ss .handleSize ;
this .mTouchPadding = ss .touchPadding ;
this .mMinFrameSize = ss .minFrameSize ;
this .mCustomRatio = new PointF (ss .customRatioX , ss .customRatioY );
this .mFrameStrokeWeight = ss .frameStrokeWeight ;
this .mGuideStrokeWeight = ss .guideStrokeWeight ;
this .mIsCropEnabled = ss .isCropEnabled ;
this .mHandleColor = ss .handleColor ;
this .mGuideColor = ss .guideColor ;
this .mInitialFrameScale = ss .initialFrameScale ;
setImageBitmap (ss .image );
requestLayout ();
}
@ Override
protected void onMeasure (int widthMeasureSpec , int heightMeasureSpec ) {
super .onMeasure (widthMeasureSpec , heightMeasureSpec );
final int viewWidth = MeasureSpec .getSize (widthMeasureSpec );
final int viewHeight = MeasureSpec .getSize (heightMeasureSpec );
setMeasuredDimension (viewWidth , viewHeight );
}
@ Override
protected void onLayout (boolean changed , int l , int t , int r , int b ) {
super .onLayout (changed , l , t , r , b );
mViewWidth = r - l - getPaddingLeft () - getPaddingRight ();
mViewHeight = b - t - getPaddingTop () - getPaddingBottom ();
if (getDrawable () != null ) initLayout (mViewWidth , mViewHeight );
}
@ Override
public void onDraw (Canvas canvas ) {
super .onDraw (canvas );
if (mIsInitialized ) {
setMatrix ();
Matrix localMatrix1 = new Matrix ();
localMatrix1 .postConcat (this .mMatrix );
Bitmap bm = getBitmap ();
if (bm != null ) {
canvas .drawBitmap (bm , localMatrix1 , mPaintBitmap );
// draw edit frame
drawEditFrame (canvas );
}
}
}
// Handle styleable ////////////////////////////////////////////////////////////////////////////
private void handleStyleable (Context context , AttributeSet attrs , int defStyle ,
float mDensity ) {
TypedArray ta = context .obtainStyledAttributes (attrs , R .styleable .CropImageView , defStyle ,
0 );
Drawable drawable ;
mCropMode = CropMode .RATIO_1_1 ;
try {
drawable = ta .getDrawable (R .styleable .CropImageView_imgSrc );
if (drawable != null ) setImageDrawable (drawable );
for (CropMode mode : CropMode .values ()) {
if (ta .getInt (R .styleable .CropImageView_cropMode , 3 ) == mode .getId ()) {
mCropMode = mode ;
break ;
}
}
mBackgroundColor = ta .getColor (R .styleable .CropImageView_backgroundColor , TRANSPARENT );
super .setBackgroundColor (mBackgroundColor );
mOverlayColor = ta .getColor (R .styleable .CropImageView_overlayColor , TRANSLUCENT_BLACK );
mFrameColor = ta .getColor (R .styleable .CropImageView_frameColor , WHITE );
mHandleColor = ta .getColor (R .styleable .CropImageView_handleColor , WHITE );
mGuideColor = ta .getColor (R .styleable .CropImageView_guideColor , TRANSLUCENT_WHITE );
for (ShowMode mode : ShowMode .values ()) {
if (ta .getInt (R .styleable .CropImageView_guideShowMode , 1 ) == mode .getId ()) {
mGuideShowMode = mode ;
break ;
}
}
for (ShowMode mode : ShowMode .values ()) {
if (ta .getInt (R .styleable .CropImageView_handleShowMode , 1 ) == mode .getId ()) {
mHandleShowMode = mode ;
break ;
}
}
setGuideShowMode (mGuideShowMode );
setHandleShowMode (mHandleShowMode );
mHandleSize = ta .getDimensionPixelSize (R .styleable .CropImageView_handleSize ,
(int ) (HANDLE_SIZE_IN_DP * mDensity ));
mTouchPadding = ta .getDimensionPixelSize (R .styleable .CropImageView_touchPadding , 0 );
mMinFrameSize = ta .getDimensionPixelSize (R .styleable .CropImageView_minFrameSize ,
(int ) (MIN_FRAME_SIZE_IN_DP * mDensity ));
mFrameStrokeWeight = ta .getDimensionPixelSize (
R .styleable .CropImageView_frameStrokeWeight ,
(int ) (FRAME_STROKE_WEIGHT_IN_DP * mDensity ));
mGuideStrokeWeight = ta .getDimensionPixelSize (
R .styleable .CropImageView_guideStrokeWeight ,
(int ) (GUIDE_STROKE_WEIGHT_IN_DP * mDensity ));
mIsCropEnabled = ta .getBoolean (R .styleable .CropImageView_cropEnabled , true );
mInitialFrameScale = constrain (ta .getFloat (R .styleable .CropImageView_initialFrameScale ,
DEFAULT_INITIAL_FRAME_SCALE ), 0.01f , 1.0f ,
DEFAULT_INITIAL_FRAME_SCALE );
} catch (Exception e ) {
e .printStackTrace ();
} finally {
ta .recycle ();
}
}
// Drawing method //////////////////////////////////////////////////////////////////////////////
private void drawEditFrame (Canvas canvas ) {
if (!mIsCropEnabled ) return ;
if (mCropMode == CropMode .CIRCLE ) {
mPaintTransparent .setFilterBitmap (true );
mPaintTransparent .setColor (mOverlayColor );
mPaintTransparent .setStyle (Paint .Style .FILL );
Path path = new Path ();
path .addRect (mImageRect .left , mImageRect .top , mImageRect .right , mImageRect .bottom ,
Path .Direction .CW );
path .addCircle ((mFrameRect .left + mFrameRect .right ) / 2 ,
(mFrameRect .top + mFrameRect .bottom ) / 2 ,
(mFrameRect .right - mFrameRect .left ) / 2 , Path .Direction .CCW );
canvas .drawPath (path , mPaintTransparent );
} else {
mPaintTransparent .setFilterBitmap (true );
mPaintTransparent .setColor (mOverlayColor );
mPaintTransparent .setStyle (Paint .Style .FILL );
canvas .drawRect (mImageRect .left , mImageRect .top , mImageRect .right , mFrameRect .top ,
mPaintTransparent );
canvas .drawRect (mImageRect .left , mFrameRect .bottom , mImageRect .right , mImageRect .bottom ,
mPaintTransparent );
canvas .drawRect (mImageRect .left , mFrameRect .top , mFrameRect .left , mFrameRect .bottom ,
mPaintTransparent );
canvas .drawRect (mFrameRect .right , mFrameRect .top , mImageRect .right , mFrameRect .bottom ,
mPaintTransparent );
}
mPaintFrame .setAntiAlias (true );
mPaintFrame .setFilterBitmap (true );
mPaintFrame .setStyle (Paint .Style .STROKE );
mPaintFrame .setColor (mFrameColor );
mPaintFrame .setStrokeWidth (mFrameStrokeWeight );
canvas .drawRect (mFrameRect .left , mFrameRect .top , mFrameRect .right , mFrameRect .bottom ,
mPaintFrame );
if (mShowGuide ) {
mPaintFrame .setColor (mGuideColor );
mPaintFrame .setStrokeWidth (mGuideStrokeWeight );
float h1 = mFrameRect .left + (mFrameRect .right - mFrameRect .left ) / 3.0f ;
float h2 = mFrameRect .right - (mFrameRect .right - mFrameRect .left ) / 3.0f ;
float v1 = mFrameRect .top + (mFrameRect .bottom - mFrameRect .top ) / 3.0f ;
float v2 = mFrameRect .bottom - (mFrameRect .bottom - mFrameRect .top ) / 3.0f ;
canvas .drawLine (h1 , mFrameRect .top , h1 , mFrameRect .bottom , mPaintFrame );
canvas .drawLine (h2 , mFrameRect .top , h2 , mFrameRect .bottom , mPaintFrame );
canvas .drawLine (mFrameRect .left , v1 , mFrameRect .right , v1 , mPaintFrame );
canvas .drawLine (mFrameRect .left , v2 , mFrameRect .right , v2 , mPaintFrame );
}
if (mShowHandle ) {
mPaintFrame .setStyle (Paint .Style .FILL );
mPaintFrame .setColor (mHandleColor );
canvas .drawCircle (mFrameRect .left , mFrameRect .top , mHandleSize , mPaintFrame );
canvas .drawCircle (mFrameRect .right , mFrameRect .top , mHandleSize , mPaintFrame );
canvas .drawCircle (mFrameRect .left , mFrameRect .bottom , mHandleSize , mPaintFrame );
canvas .drawCircle (mFrameRect .right , mFrameRect .bottom , mHandleSize , mPaintFrame );
}
}
private void setMatrix () {
mMatrix .reset ();
mMatrix .setTranslate (mCenter .x - mImgWidth * 0.5f , mCenter .y - mImgHeight * 0.5f );
mMatrix .postScale (mScale , mScale , mCenter .x , mCenter .y );
mMatrix .postRotate (mAngle , mCenter .x , mCenter .y );
}
// Initializer /////////////////////////////////////////////////////////////////////////////////
private void initLayout (int viewW , int viewH ) {
mImgWidth = getDrawable ().getIntrinsicWidth ();
mImgHeight = getDrawable ().getIntrinsicHeight ();
if (mImgWidth <= 0 ) mImgWidth = viewW ;
if (mImgHeight <= 0 ) mImgHeight = viewH ;
float w = (float ) viewW ;
float h = (float ) viewH ;
float viewRatio = w / h ;
float imgRatio = mImgWidth / mImgHeight ;
float scale = 1.0f ;
if (imgRatio >= viewRatio ) {
scale = w / mImgWidth ;
} else if (imgRatio < viewRatio ) {
scale = h / mImgHeight ;
}
setCenter (new PointF (getPaddingLeft () + w * 0.5f , getPaddingTop () + h * 0.5f ));
setScale (scale );
initCropFrame ();
adjustRatio ();
mIsInitialized = true ;
}
private void initCropFrame () {
setMatrix ();
float [] arrayOfFloat = new float [8 ];
arrayOfFloat [0 ] = 0.0f ;
arrayOfFloat [1 ] = 0.0f ;
arrayOfFloat [2 ] = 0.0f ;
arrayOfFloat [3 ] = 10000 ;
arrayOfFloat [4 ] = 100000 ;
arrayOfFloat [5 ] = 0.0f ;
arrayOfFloat [6 ] = mImgWidth ;
arrayOfFloat [7 ] = mImgHeight ;
mMatrix .mapPoints (arrayOfFloat );
float l = arrayOfFloat [0 ];
float t = arrayOfFloat [1 ];
float r = arrayOfFloat [6 ];
float b = arrayOfFloat [7 ];
mFrameRect = new RectF (l , t , r , b );
mImageRect = new RectF (l , t , r , b );
}
// Touch Event /////////////////////////////////////////////////////////////////////////////////
@ Override
public boolean onTouchEvent (MotionEvent event ) {
if (!mIsInitialized ) return false ;
if (!mIsCropEnabled ) return false ;
if (!mIsEnabled ) return false ;
switch (event .getAction ()) {
case MotionEvent .ACTION_DOWN :
onDown (event );
return true ;
case MotionEvent .ACTION_MOVE :
onMove (event );
if (mTouchArea != TouchArea .OUT_OF_BOUNDS ) {
getParent ().requestDisallowInterceptTouchEvent (true );
}
return true ;
case MotionEvent .ACTION_CANCEL :
getParent ().requestDisallowInterceptTouchEvent (false );
onCancel ();
return true ;
case MotionEvent .ACTION_UP :
getParent ().requestDisallowInterceptTouchEvent (false );
onUp (event );
return true ;
}
return false ;
}
private void onDown (MotionEvent e ) {
invalidate ();
mLastX = e .getX ();
mLastY = e .getY ();
checkTouchArea (e .getX (), e .getY ());
}
private void onMove (MotionEvent e ) {
float diffX = e .getX () - mLastX ;
float diffY = e .getY () - mLastY ;
switch (mTouchArea ) {
case CENTER :
moveFrame (diffX , diffY );
break ;
case LEFT_TOP :
moveHandleLT (diffX , diffY );
break ;
case RIGHT_TOP :
moveHandleRT (diffX , diffY );
break ;
case LEFT_BOTTOM :
moveHandleLB (diffX , diffY );
break ;
case RIGHT_BOTTOM :
moveHandleRB (diffX , diffY );
break ;
case OUT_OF_BOUNDS :
break ;
}
invalidate ();
mLastX = e .getX ();
mLastY = e .getY ();
}
private void onUp (MotionEvent e ) {
if (mGuideShowMode == ShowMode .SHOW_ON_TOUCH ) mShowGuide = false ;
if (mHandleShowMode == ShowMode .SHOW_ON_TOUCH ) mShowHandle = false ;
mTouchArea = TouchArea .OUT_OF_BOUNDS ;
invalidate ();
}
private void onCancel () {
mTouchArea = TouchArea .OUT_OF_BOUNDS ;
invalidate ();
}
// Hit test ////////////////////////////////////////////////////////////////////////////////////
private void checkTouchArea (float x , float y ) {
if (isInsideCornerLeftTop (x , y )) {
mTouchArea = TouchArea .LEFT_TOP ;
if (mHandleShowMode == ShowMode .SHOW_ON_TOUCH ) mShowHandle = true ;
if (mGuideShowMode == ShowMode .SHOW_ON_TOUCH ) mShowGuide = true ;
return ;
}
if (isInsideCornerRightTop (x , y )) {
mTouchArea = TouchArea .RIGHT_TOP ;
if (mHandleShowMode == ShowMode .SHOW_ON_TOUCH ) mShowHandle = true ;
if (mGuideShowMode == ShowMode .SHOW_ON_TOUCH ) mShowGuide = true ;
return ;
}
if (isInsideCornerLeftBottom (x , y )) {
mTouchArea = TouchArea .LEFT_BOTTOM ;
if (mHandleShowMode == ShowMode .SHOW_ON_TOUCH ) mShowHandle = true ;
if (mGuideShowMode == ShowMode .SHOW_ON_TOUCH ) mShowGuide = true ;
return ;
}
if (isInsideCornerRightBottom (x , y )) {
mTouchArea = TouchArea .RIGHT_BOTTOM ;
if (mHandleShowMode == ShowMode .SHOW_ON_TOUCH ) mShowHandle = true ;
if (mGuideShowMode == ShowMode .SHOW_ON_TOUCH ) mShowGuide = true ;
return ;
}
if (isInsideFrame (x , y )) {
if (mGuideShowMode == ShowMode .SHOW_ON_TOUCH ) mShowGuide = true ;
mTouchArea = TouchArea .CENTER ;
return ;
}
mTouchArea = TouchArea .OUT_OF_BOUNDS ;
}
private boolean isInsideFrame (float x , float y ) {
if (mFrameRect .left <= x && mFrameRect .right >= x ) {
if (mFrameRect .top <= y && mFrameRect .bottom >= y ) {
mTouchArea = TouchArea .CENTER ;
return true ;
}
}
return false ;
}
private boolean isInsideCornerLeftTop (float x , float y ) {
float dx = x - mFrameRect .left ;
float dy = y - mFrameRect .top ;
float d = dx * dx + dy * dy ;
return sq (mHandleSize + mTouchPadding ) >= d ;
}
private boolean isInsideCornerRightTop (float x , float y ) {
float dx = x - mFrameRect .right ;
float dy = y - mFrameRect .top ;
float d = dx * dx + dy * dy ;
return sq (mHandleSize + mTouchPadding ) >= d ;
}
private boolean isInsideCornerLeftBottom (float x , float y ) {
float dx = x - mFrameRect .left ;
float dy = y - mFrameRect .bottom ;
float d = dx * dx + dy * dy ;
return sq (mHandleSize + mTouchPadding ) >= d ;
}
private boolean isInsideCornerRightBottom (float x , float y ) {
float dx = x - mFrameRect .right ;
float dy = y - mFrameRect .bottom ;
float d = dx * dx + dy * dy ;
return sq (mHandleSize + mTouchPadding ) >= d ;
}
// Adjust frame ////////////////////////////////////////////////////////////////////////////////
private void moveFrame (float x , float y ) {
mFrameRect .left += x ;
mFrameRect .right += x ;
mFrameRect .top += y ;
mFrameRect .bottom += y ;
checkMoveBounds ();
}
private void moveHandleLT (float diffX , float diffY ) {
if (mCropMode == CropMode .RATIO_FREE ) {
mFrameRect .left += diffX ;
mFrameRect .top += diffY ;
if (isWidthTooSmall ()) {
float offsetX = mMinFrameSize - getFrameW ();
mFrameRect .left -= offsetX ;
}
if (isHeightTooSmall ()) {
float offsetY = mMinFrameSize - getFrameH ();
mFrameRect .top -= offsetY ;
}
checkScaleBounds ();
} else {
float dx = diffX ;
float dy = diffX * getRatioY () / getRatioX ();
mFrameRect .left += dx ;
mFrameRect .top += dy ;
if (isWidthTooSmall ()) {
float offsetX = mMinFrameSize - getFrameW ();
mFrameRect .left -= offsetX ;
float offsetY = offsetX * getRatioY () / getRatioX ();
mFrameRect .top -= offsetY ;
}
if (isHeightTooSmall ()) {
float offsetY = mMinFrameSize - getFrameH ();
mFrameRect .top -= offsetY ;
float offsetX = offsetY * getRatioX () / getRatioY ();
mFrameRect .left -= offsetX ;
}
float ox , oy ;
if (!isInsideHorizontal (mFrameRect .left )) {
ox = mImageRect .left - mFrameRect .left ;
mFrameRect .left += ox ;
oy = ox * getRatioY () / getRatioX ();
mFrameRect .top += oy ;
}
if (!isInsideVertical (mFrameRect .top )) {
oy = mImageRect .top - mFrameRect .top ;
mFrameRect .top += oy ;
ox = oy * getRatioX () / getRatioY ();
mFrameRect .left += ox ;
}
}
}
private void moveHandleRT (float diffX , float diffY ) {
if (mCropMode == CropMode .RATIO_FREE ) {
mFrameRect .right += diffX ;
mFrameRect .top += diffY ;
if (isWidthTooSmall ()) {
float offsetX = mMinFrameSize - getFrameW ();
mFrameRect .right += offsetX ;
}
if (isHeightTooSmall ()) {
float offsetY = mMinFrameSize - getFrameH ();
mFrameRect .top -= offsetY ;
}
checkScaleBounds ();
} else {
float dx = diffX ;
float dy = diffX * getRatioY () / getRatioX ();
mFrameRect .right += dx ;
mFrameRect .top -= dy ;
if (isWidthTooSmall ()) {
float offsetX = mMinFrameSize - getFrameW ();
mFrameRect .right += offsetX ;
float offsetY = offsetX * getRatioY () / getRatioX ();
mFrameRect .top -= offsetY ;
}
if (isHeightTooSmall ()) {
float offsetY = mMinFrameSize - getFrameH ();
mFrameRect .top -= offsetY ;
float offsetX = offsetY * getRatioX () / getRatioY ();
mFrameRect .right += offsetX ;
}
float ox , oy ;
if (!isInsideHorizontal (mFrameRect .right )) {
ox = mFrameRect .right - mImageRect .right ;
mFrameRect .right -= ox ;
oy = ox * getRatioY () / getRatioX ();
mFrameRect .top += oy ;
}
if (!isInsideVertical (mFrameRect .top )) {
oy = mImageRect .top - mFrameRect .top ;
mFrameRect .top += oy ;
ox = oy * getRatioX () / getRatioY ();
mFrameRect .right -= ox ;
}
}
}
private void moveHandleLB (float diffX , float diffY ) {
if (mCropMode == CropMode .RATIO_FREE ) {
mFrameRect .left += diffX ;
mFrameRect .bottom += diffY ;
if (isWidthTooSmall ()) {
float offsetX = mMinFrameSize - getFrameW ();
mFrameRect .left -= offsetX ;
}
if (isHeightTooSmall ()) {
float offsetY = mMinFrameSize - getFrameH ();
mFrameRect .bottom += offsetY ;
}
checkScaleBounds ();
} else {
float dx = diffX ;
float dy = diffX * getRatioY () / getRatioX ();
mFrameRect .left += dx ;
mFrameRect .bottom -= dy ;
if (isWidthTooSmall ()) {
float offsetX = mMinFrameSize - getFrameW ();
mFrameRect .left -= offsetX ;
float offsetY = offsetX * getRatioY () / getRatioX ();
mFrameRect .bottom += offsetY ;
}
if (isHeightTooSmall ()) {
float offsetY = mMinFrameSize - getFrameH ();
mFrameRect .bottom += offsetY ;
float offsetX = offsetY * getRatioX () / getRatioY ();
mFrameRect .left -= offsetX ;
}
float ox , oy ;
if (!isInsideHorizontal (mFrameRect .left )) {
ox = mImageRect .left - mFrameRect .left ;
mFrameRect .left += ox ;
oy = ox * getRatioY () / getRatioX ();
mFrameRect .bottom -= oy ;
}
if (!isInsideVertical (mFrameRect .bottom )) {
oy = mFrameRect .bottom - mImageRect .bottom ;
mFrameRect .bottom -= oy ;
ox = oy * getRatioX () / getRatioY ();
mFrameRect .left += ox ;
}
}
}
private void moveHandleRB (float diffX , float diffY ) {
if (mCropMode == CropMode .RATIO_FREE ) {
mFrameRect .right += diffX ;
mFrameRect .bottom += diffY ;
if (isWidthTooSmall ()) {
float offsetX = mMinFrameSize - getFrameW ();
mFrameRect .right += offsetX ;
}
if (isHeightTooSmall ()) {
float offsetY = mMinFrameSize - getFrameH ();
mFrameRect .bottom += offsetY ;
}
checkScaleBounds ();
} else {
float dx = diffX ;
float dy = diffX * getRatioY () / getRatioX ();
mFrameRect .right += dx ;
mFrameRect .bottom += dy ;
if (isWidthTooSmall ()) {
float offsetX = mMinFrameSize - getFrameW ();
mFrameRect .right += offsetX ;
float offsetY = offsetX * getRatioY () / getRatioX ();
mFrameRect .bottom += offsetY ;
}
if (isHeightTooSmall ()) {
float offsetY = mMinFrameSize - getFrameH ();
mFrameRect .bottom += offsetY ;
float offsetX = offsetY * getRatioX () / getRatioY ();
mFrameRect .right += offsetX ;
}
float ox , oy ;
if (!isInsideHorizontal (mFrameRect .right )) {
ox = mFrameRect .right - mImageRect .right ;
mFrameRect .right -= ox ;
oy = ox * getRatioY () / getRatioX ();
mFrameRect .bottom -= oy ;
}
if (!isInsideVertical (mFrameRect .bottom )) {
oy = mFrameRect .bottom - mImageRect .bottom ;
mFrameRect .bottom -= oy ;
ox = oy * getRatioX () / getRatioY ();
mFrameRect .right -= ox ;
}
}
}
// Frame position correction ///////////////////////////////////////////////////////////////////
private void checkScaleBounds () {
float lDiff = mFrameRect .left - mImageRect .left ;
float rDiff = mFrameRect .right - mImageRect .right ;
float tDiff = mFrameRect .top - mImageRect .top ;
float bDiff = mFrameRect .bottom - mImageRect .bottom ;
if (lDiff < 0 ) {
mFrameRect .left -= lDiff ;
}
if (rDiff > 0 ) {
mFrameRect .right -= rDiff ;
}
if (tDiff < 0 ) {
mFrameRect .top -= tDiff ;
}
if (bDiff > 0 ) {
mFrameRect .bottom -= bDiff ;
}
}
private void checkMoveBounds () {
float diff = mFrameRect .left - mImageRect .left ;
if (diff < 0 ) {
mFrameRect .left -= diff ;
mFrameRect .right -= diff ;
}
diff = mFrameRect .right - mImageRect .right ;
if (diff > 0 ) {
mFrameRect .left -= diff ;
mFrameRect .right -= diff ;
}
diff = mFrameRect .top - mImageRect .top ;
if (diff < 0 ) {
mFrameRect .top -= diff ;
mFrameRect .bottom -= diff ;
}
diff = mFrameRect .bottom - mImageRect .bottom ;
if (diff > 0 ) {
mFrameRect .top -= diff ;
mFrameRect .bottom -= diff ;
}
}
private boolean isInsideHorizontal (float x ) {
return mImageRect .left <= x && mImageRect .right >= x ;
}
private boolean isInsideVertical (float y ) {
return mImageRect .top <= y && mImageRect .bottom >= y ;
}
private boolean isWidthTooSmall () {
return getFrameW () < mMinFrameSize ;
}
private boolean isHeightTooSmall () {
return getFrameH () < mMinFrameSize ;
}
// Frame aspect ratio correction ///////////////////////////////////////////////////////////////
private void adjustRatio () {
if (mImageRect == null ) return ;
float imgW = mImageRect .right - mImageRect .left ;
float imgH = mImageRect .bottom - mImageRect .top ;
float frameW = getRatioX (imgW );
float frameH = getRatioY (imgH );
float imgRatio = imgW / imgH ;
float frameRatio = frameW / frameH ;
float l = mImageRect .left , t = mImageRect .top , r = mImageRect .right , b = mImageRect .bottom ;
if (frameRatio >= imgRatio ) {
l = mImageRect .left ;
r = mImageRect .right ;
float hy = (mImageRect .top + mImageRect .bottom ) * 0.5f ;
float hh = (imgW / frameRatio ) * 0.5f ;
t = hy - hh ;
b = hy + hh ;
} else if (frameRatio < imgRatio ) {
t = mImageRect .top ;
b = mImageRect .bottom ;
float hx = (mImageRect .left + mImageRect .right ) * 0.5f ;
float hw = imgH * frameRatio * 0.5f ;
l = hx - hw ;
r = hx + hw ;
}
float w = r - l ;
float h = b - t ;
float cx = l + w / 2 ;
float cy = t + h / 2 ;
float sw = w * mInitialFrameScale ;
float sh = h * mInitialFrameScale ;
mFrameRect = new RectF (cx - sw / 2 , cy - sh / 2 , cx + sw / 2 , cy + sh / 2 );
invalidate ();
}
private float getRatioX (float w ) {
switch (mCropMode ) {
case RATIO_FIT_IMAGE :
return mImgWidth ;
case RATIO_FREE :
return w ;
case RATIO_4_3 :
return 4.0f ;
case RATIO_3_4 :
return 3.0f ;
case RATIO_16_9 :
return 16.0f ;
case RATIO_9_16 :
return 9.0f ;
case RATIO_1_1 :
case CIRCLE :
return 1.0f ;
case RATIO_CUSTOM :
return mCustomRatio .x ;
default :
return w ;
}
}
private float getRatioY (float h ) {
switch (mCropMode ) {
case RATIO_FIT_IMAGE :
return mImgHeight ;
case RATIO_FREE :
return h ;
case RATIO_4_3 :
return 3.0f ;
case RATIO_3_4 :
return 4.0f ;
case RATIO_16_9 :
return 9.0f ;
case RATIO_9_16 :
return 16.0f ;
case RATIO_1_1 :
case CIRCLE :
return 1.0f ;
case RATIO_CUSTOM :
return mCustomRatio .y ;
default :
return h ;
}
}
private float getRatioX () {
switch (mCropMode ) {
case RATIO_FIT_IMAGE :
return mImgWidth ;
case RATIO_4_3 :
return 4.0f ;
case RATIO_3_4 :
return 3.0f ;
case RATIO_16_9 :
return 16.0f ;
case RATIO_9_16 :
return 9.0f ;
case RATIO_1_1 :
case CIRCLE :
return 1.0f ;
case RATIO_CUSTOM :
return mCustomRatio .x ;
default :
return 1.0f ;
}
}
private float getRatioY () {
switch (mCropMode ) {
case RATIO_FIT_IMAGE :
return mImgHeight ;
case RATIO_4_3 :
return 3.0f ;
case RATIO_3_4 :
return 4.0f ;
case RATIO_16_9 :
return 9.0f ;
case RATIO_9_16 :
return 16.0f ;
case RATIO_1_1 :
case CIRCLE :
return 1.0f ;
case RATIO_CUSTOM :
return mCustomRatio .y ;
default :
return 1.0f ;
}
}
// Utility methods /////////////////////////////////////////////////////////////////////////////
private float getDensity () {
DisplayMetrics displayMetrics = new DisplayMetrics ();
((WindowManager ) getContext ().getSystemService (Context .WINDOW_SERVICE )).getDefaultDisplay ()
.getMetrics (displayMetrics );
return displayMetrics .density ;
}
private float sq (float value ) {
return value * value ;
}
private float constrain (float val , float min , float max , float defaultVal ) {
if (val < min || val > max ) return defaultVal ;
return val ;
}
// Public methods //////////////////////////////////////////////////////////////////////////////
/**
* Get source image bitmap
*
* @return src bitmap
*/
public Bitmap getImageBitmap () {
return getBitmap ();
}
/**
* Set source image bitmap
*
* @param bitmap src image bitmap
*/
@ Override
public void setImageBitmap (Bitmap bitmap ) {
mIsInitialized = false ;
super .setImageBitmap (bitmap );
updateDrawableInfo ();
}
/**
* Set source image resource id
*
* @param resId source image resource id
*/
@ Override
public void setImageResource (int resId ) {
mIsInitialized = false ;
super .setImageResource (resId );
updateDrawableInfo ();
}
/**
* Set image drawable.
*
* @param drawable
*/
@ Override
public void setImageDrawable (Drawable drawable ) {
mIsInitialized = false ;
super .setImageDrawable (drawable );
updateDrawableInfo ();
}
/**
* Set image uri
*
* @param uri
*/
@ Override
public void setImageURI (Uri uri ) {
mIsInitialized = false ;
super .setImageURI (uri );
updateDrawableInfo ();
}
@ Override
public void setScaleType (ScaleType scaleType ) {
super .setScaleType (ScaleType .FIT_XY );
}
private void updateDrawableInfo () {
Drawable d = getDrawable ();
if (d != null ) {
initLayout (mViewWidth , mViewHeight );
}
}
/**
* Rotate image.
*
* @param degrees angle of ration in degrees.
*/
public void rotateImage (RotateDegrees degrees ) {
Bitmap source = getBitmap ();
if (source == null ) return ;
int angle = degrees .getValue ();
Matrix matrix = new Matrix ();
matrix .postRotate (angle );
Bitmap rotated = Bitmap .createBitmap (source , 0 , 0 , source .getWidth (), source .getHeight (),
matrix , true );
setImageBitmap (rotated );
}
/**
* Saves the Bitmap as a PNG file at path 'fullPath'
*
* @return true if it successfully saved, false otherwise
* path in form of(Environment.getExternalStorageDirectory().toString() +"/" + "folderName";);
*/
public boolean saveBitmapInToFolder () {
if (getCroppedBitmap () == null )
return false ;
boolean fileCreated = false ;
boolean bitmapCompressed = false ;
boolean streamClosed = false ;
String filePath = Environment .getExternalStorageDirectory ().toString () + "/" + "Goparites" ;
File fileMake = new File (filePath );
if (!fileMake .exists ()) {
fileMake .mkdir ();
}
imageName = filePath + "/" + "image" + System .currentTimeMillis () + ".png" ;
File imageFile = new File (imageName );
if (imageFile .exists ())
if (!imageFile .delete ())
return false ;
try {
fileCreated = imageFile .createNewFile ();
} catch (IOException e ) {
e .printStackTrace ();
}
FileOutputStream out = null ;
try {
out = new FileOutputStream (imageFile );
bitmapCompressed = getCroppedBitmap ().compress (Bitmap .CompressFormat .PNG , 100 , out );
} catch (Exception e ) {
e .printStackTrace ();
bitmapCompressed = false ;
} finally {
if (out != null ) {
try {
out .flush ();
out .close ();
streamClosed = true ;
} catch (IOException e ) {
e .printStackTrace ();
streamClosed = false ;
}
}
}
return (fileCreated && bitmapCompressed && streamClosed );
}
public Uri getImageUri () {
Uri uri = Uri .fromFile (new File (imageName ));
return uri ;
}
/**
* Get cropped image bitmap
*
* @return cropped image bitmap
*/
public Bitmap getCroppedBitmap () {
Bitmap source = getBitmap ();
if (source == null ) return null ;
int x , y , w , h ;
float l = (mFrameRect .left / mScale );
float t = (mFrameRect .top / mScale );
float r = (mFrameRect .right / mScale );
float b = (mFrameRect .bottom / mScale );
x = Math .round (l - (mImageRect .left / mScale ));
y = Math .round (t - (mImageRect .top / mScale ));
w = Math .round (r - l );
h = Math .round (b - t );
if (x + w > source .getWidth ()) {
w = source .getWidth () - x ;
}
if (y + h > source .getHeight ()) {
h = source .getHeight () - y ;
}
Bitmap cropped = Bitmap .createBitmap (source , x , y , w , h , null , false );
if (mCropMode != CropMode .CIRCLE ) return cropped ;
return getCircularBitmap (cropped );
}
/**
* Get cropped rect image bitmap
* <p/>
* This method always returns rect image.
* (If you need a square image with CropMode.CIRCLE, you can use this method.)
*
* @return cropped image bitmap
*/
public Bitmap getRectBitmap () {
Bitmap source = getBitmap ();
if (source == null ) return null ;
int x , y , w , h ;
float l = (mFrameRect .left / mScale );
float t = (mFrameRect .top / mScale );
float r = (mFrameRect .right / mScale );
float b = (mFrameRect .bottom / mScale );
x = Math .round (l - (mImageRect .left / mScale ));
y = Math .round (t - (mImageRect .top / mScale ));
w = Math .round (r - l );
h = Math .round (b - t );
if (x + w > source .getWidth ()) {
w = source .getWidth () - x ;
}
if (y + h > source .getHeight ()) {
h = source .getHeight () - y ;
}
return Bitmap .createBitmap (source , x , y , w , h , null , false );
}
/**
* Crop the square image in a circular
*
* @param square image bitmap
* @return circular image bitmap
*/
public Bitmap getCircularBitmap (Bitmap square ) {
if (square == null ) return null ;
Bitmap output = Bitmap .createBitmap (square .getWidth (), square .getHeight (),
Bitmap .Config .ARGB_8888 );
final Rect rect = new Rect (0 , 0 , square .getWidth (), square .getHeight ());
Canvas canvas = new Canvas (output );
int halfWidth = square .getWidth () / 2 ;
int halfHeight = square .getHeight () / 2 ;
final Paint paint = new Paint ();
paint .setAntiAlias (true );
paint .setFilterBitmap (true );
canvas .drawCircle (halfWidth , halfHeight , Math .min (halfWidth , halfHeight ), paint );
paint .setXfermode (new PorterDuffXfermode (PorterDuff .Mode .SRC_IN ));
canvas .drawBitmap (square , rect , rect , paint );
return output ;
}
private Bitmap getBitmap () {
Bitmap bm = null ;
Drawable d = getDrawable ();
if (d != null && d instanceof BitmapDrawable ) bm = ((BitmapDrawable ) d ).getBitmap ();
return bm ;
}
/**
* Get frame position relative to the source bitmap.
*
* @return crop area boundaries.
*/
public RectF getActualCropRect () {
float offsetX = (mImageRect .left / mScale );
float offsetY = (mImageRect .top / mScale );
float l = (mFrameRect .left / mScale ) - offsetX ;
float t = (mFrameRect .top / mScale ) - offsetY ;
float r = (mFrameRect .right / mScale ) - offsetX ;
float b = (mFrameRect .bottom / mScale ) - offsetY ;
return new RectF (l , t , r , b );
}
/**
* Set crop mode
*
* @param mode crop mode
*/
public void setCropMode (CropMode mode ) {
if (mode == CropMode .RATIO_CUSTOM ) {
setCustomRatio (1 , 1 );
} else {
mCropMode = mode ;
adjustRatio ();
}
}
/**
* Set custom aspect ratio to crop frame
*
* @param ratioX aspect ratio X
* @param ratioY aspect ratio Y
*/
public void setCustomRatio (int ratioX , int ratioY ) {
if (ratioX == 0 || ratioY == 0 ) return ;
mCropMode = CropMode .RATIO_CUSTOM ;
mCustomRatio = new PointF (ratioX , ratioY );
adjustRatio ();
}
/**
* Set image overlay color
*
* @param overlayColor color resId or color int(ex. 0xFFFFFFFF)
*/
public void setOverlayColor (int overlayColor ) {
this .mOverlayColor = overlayColor ;
invalidate ();
}
/**
* Set crop frame color
*
* @param frameColor color resId or color int(ex. 0xFFFFFFFF)
*/
public void setFrameColor (int frameColor ) {
this .mFrameColor = frameColor ;
invalidate ();
}
/**
* Set handle color
*
* @param handleColor color resId or color int(ex. 0xFFFFFFFF)
*/
public void setHandleColor (int handleColor ) {
this .mHandleColor = handleColor ;
invalidate ();
}
/**
* Set guide color
*
* @param guideColor color resId or color int(ex. 0xFFFFFFFF)
*/
public void setGuideColor (int guideColor ) {
this .mGuideColor = guideColor ;
invalidate ();
}
/**
* Set view background color
*
* @param bgColor color resId or color int(ex. 0xFFFFFFFF)
*/
public void setBackgroundColor (int bgColor ) {
this .mBackgroundColor = bgColor ;
super .setBackgroundColor (this .mBackgroundColor );
invalidate ();
}
/**
* Set crop frame minimum size in density-independent pixels.
*
* @param minDp crop frame minimum size in density-independent pixels
*/
public void setMinFrameSizeInDp (int minDp ) {
mMinFrameSize = minDp * getDensity ();
}
/**
* Set crop frame minimum size in pixels.
*
* @param minPx crop frame minimum size in pixels
*/
public void setMinFrameSizeInPx (int minPx ) {
mMinFrameSize = minPx ;
}
/**
* Set handle radius in density-independent pixels.
*
* @param handleDp handle radius in density-independent pixels
*/
public void setHandleSizeInDp (int handleDp ) {
mHandleSize = (int ) (handleDp * getDensity ());
}
/**
* Set crop frame handle touch padding(touch area) in density-independent pixels.
* <p/>
* handle touch area : a circle of radius R.(R = handle size + touch padding)
*
* @param paddingDp crop frame handle touch padding(touch area) in density-independent pixels
*/
public void setTouchPaddingInDp (int paddingDp ) {
mTouchPadding = (int ) (paddingDp * getDensity ());
}
/**
* Set guideline show mode.
* (SHOW_ALWAYS/NOT_SHOW/SHOW_ON_TOUCH)
*
* @param mode guideline show mode
*/
public void setGuideShowMode (ShowMode mode ) {
mGuideShowMode = mode ;
switch (mode ) {
case SHOW_ALWAYS :
mShowGuide = true ;
break ;
case NOT_SHOW :
case SHOW_ON_TOUCH :
mShowGuide = false ;
break ;
}
invalidate ();
}
/**
* Set handle show mode.
* (SHOW_ALWAYS/NOT_SHOW/SHOW_ON_TOUCH)
*
* @param mode handle show mode
*/
public void setHandleShowMode (ShowMode mode ) {
mHandleShowMode = mode ;
switch (mode ) {
case SHOW_ALWAYS :
mShowHandle = true ;
break ;
case NOT_SHOW :
case SHOW_ON_TOUCH :
mShowHandle = false ;
break ;
}
invalidate ();
}
/**
* Set frame stroke weight in density-independent pixels.
*
* @param weightDp frame stroke weight in density-independent pixels.
*/
public void setFrameStrokeWeightInDp (int weightDp ) {
mFrameStrokeWeight = weightDp * getDensity ();
invalidate ();
}
/**
* Set guideline stroke weight in density-independent pixels.
*
* @param weightDp guideline stroke weight in density-independent pixels.
*/
public void setGuideStrokeWeightInDp (int weightDp ) {
mGuideStrokeWeight = weightDp * getDensity ();
invalidate ();
}
/**
* Set whether to show crop frame.
*
* @param enabled should show crop frame?
*/
public void setCropEnabled (boolean enabled ) {
mIsCropEnabled = enabled ;
invalidate ();
}
/**
* Set locking the crop frame.
*
* @param enabled should lock crop frame?
*/
@ Override
public void setEnabled (boolean enabled ) {
super .setEnabled (enabled );
mIsEnabled = enabled ;
}
/**
* Set initial scale of the frame.(0.01 ~ 1.0)
*
* @param initialScale initial scale
*/
public void setInitialFrameScale (float initialScale ) {
mInitialFrameScale = constrain (initialScale , 0.01f , 1.0f , DEFAULT_INITIAL_FRAME_SCALE );
}
private void setScale (float mScale ) {
this .mScale = mScale ;
}
private void setCenter (PointF mCenter ) {
this .mCenter = mCenter ;
}
private float getFrameW () {
return (mFrameRect .right - mFrameRect .left );
}
private float getFrameH () {
return (mFrameRect .bottom - mFrameRect .top );
}
// Enum ////////////////////////////////////////////////////////////////////////////////////////
private enum TouchArea {
OUT_OF_BOUNDS , CENTER , LEFT_TOP , RIGHT_TOP , LEFT_BOTTOM , RIGHT_BOTTOM ;
}
public enum CropMode {
RATIO_FIT_IMAGE (0 ), RATIO_4_3 (1 ), RATIO_3_4 (2 ), RATIO_1_1 (3 ), RATIO_16_9 (4 ), RATIO_9_16 (
5 ), RATIO_FREE (6 ), RATIO_CUSTOM (7 ), CIRCLE (8 );
private final int ID ;
private CropMode (final int id ) {
this .ID = id ;
}
public int getId () {
return ID ;
}
}
public enum ShowMode {
SHOW_ALWAYS (1 ), SHOW_ON_TOUCH (2 ), NOT_SHOW (3 );
private final int ID ;
private ShowMode (final int id ) {
this .ID = id ;
}
public int getId () {
return ID ;
}
}
public enum RotateDegrees {
ROTATE_90D (90 ), ROTATE_180D (180 ), ROTATE_270D (270 );
private final int VALUE ;
private RotateDegrees (final int value ) {
this .VALUE = value ;
}
public int getValue () {
return VALUE ;
}
}
// Save/Restore support ////////////////////////////////////////////////////////////////////////
public static class SavedState extends BaseSavedState {
Bitmap image ;
CropMode mode ;
int backgroundColor ;
int overlayColor ;
int frameColor ;
ShowMode guideShowMode ;
ShowMode handleShowMode ;
boolean showGuide ;
boolean showHandle ;
int handleSize ;
int touchPadding ;
float minFrameSize ;
float customRatioX ;
float customRatioY ;
float frameStrokeWeight ;
float guideStrokeWeight ;
boolean isCropEnabled ;
int handleColor ;
int guideColor ;
float initialFrameScale ;
SavedState (Parcelable superState ) {
super (superState );
}
private SavedState (Parcel in ) {
super (in );
image = in .readParcelable (Bitmap .class .getClassLoader ());
mode = (CropMode ) in .readSerializable ();
backgroundColor = in .readInt ();
overlayColor = in .readInt ();
frameColor = in .readInt ();
guideShowMode = (ShowMode ) in .readSerializable ();
handleShowMode = (ShowMode ) in .readSerializable ();
showGuide = (in .readInt () != 0 );
showHandle = (in .readInt () != 0 );
handleSize = in .readInt ();
touchPadding = in .readInt ();
minFrameSize = in .readFloat ();
customRatioX = in .readFloat ();
customRatioY = in .readFloat ();
frameStrokeWeight = in .readFloat ();
guideStrokeWeight = in .readFloat ();
isCropEnabled = (in .readInt () != 0 );
handleColor = in .readInt ();
guideColor = in .readInt ();
initialFrameScale = in .readFloat ();
}
@ Override
public void writeToParcel (Parcel out , int flag ) {
super .writeToParcel (out , flag );
out .writeParcelable (image , flag );
out .writeSerializable (mode );
out .writeInt (backgroundColor );
out .writeInt (overlayColor );
out .writeInt (frameColor );
out .writeSerializable (guideShowMode );
out .writeSerializable (handleShowMode );
out .writeInt (showGuide ? 1 : 0 );
out .writeInt (showHandle ? 1 : 0 );
out .writeInt (handleSize );
out .writeInt (touchPadding );
out .writeFloat (minFrameSize );
out .writeFloat (customRatioX );
out .writeFloat (customRatioY );
out .writeFloat (frameStrokeWeight );
out .writeFloat (guideStrokeWeight );
out .writeInt (isCropEnabled ? 1 : 0 );
out .writeInt (handleColor );
out .writeInt (guideColor );
out .writeFloat (initialFrameScale );
}
public static final Parcelable .Creator CREATOR = new Parcelable .Creator () {
public SavedState createFromParcel (final Parcel inParcel ) {
return new SavedState (inParcel );
}
public SavedState [] newArray (final int inSize ) {
return new SavedState [inSize ];
}
};
}
}