Android Open Source - CropImageView Crop Image View






From Project

Back to project page CropImageView.

License

The source code is released under:

Copyright (c) 2014 Josh Holtz <josh@rokkincat.com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), t...

If you think the Android project CropImageView listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.joshholtz.cropimageview;
/*from  w w w  . j av  a2 s  . c  o  m*/
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.graphics.drawable.shapes.RectShape;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

public class CropImageView extends FrameLayout implements View.OnTouchListener {
  
  private final static String TAG = "CropImageView";
  
  private final static int HEIGHT_OF_DRAGGER = 45;
  private final static int INITIAL_MARGIN_OF_DRAGGER = 60;
  
  private ImageView mImageView;
  private ImageView mTopLeftDragger;
  private ImageView mBottomRightDragger;
  private ImageView mDaBox;
  
  private  Drawable mDraggerDrawable;
  private  Drawable mCropDrawable;
  
  private boolean mKeepSquare;
  
  private Bitmap mBitmap;
  
  public CropImageView(Context context) {
    super(context);
    init();
  }
  
  public CropImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
  }

  public CropImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
  }
  
  public void setImageBitmap(Bitmap bm) { 
    if (mImageView != null) {
      mBitmap = bm;
      mImageView.setImageBitmap(bm);
    }
  }
  
  public void setCornerDrawable(int color, int width, int height) {
    mDraggerDrawable = this.getCircleDrawable(color, width, height);
    
    if (mTopLeftDragger != null) {
      mTopLeftDragger.setImageDrawable(mDraggerDrawable);
    }
    
    if (mBottomRightDragger != null) {
      mBottomRightDragger.setImageDrawable(mDraggerDrawable);
    }
  }
  
  public void setKeepSquare(boolean keepSquare) {
    mKeepSquare = keepSquare;
    
    if (mTopLeftDragger != null && mBottomRightDragger != null) {
      Log.d(TAG, "Draggers exist");
    } else {
      Log.d(TAG, "Draggers don't exist");
    }
  }
  
  public void setCropAreaDrawable(int fillColor, int fillAlpha, int strokeColor, int strokeAlpha, int strokeWidth) {
    mCropDrawable = this.getCropDrawable(fillColor, fillAlpha, strokeColor, strokeAlpha, strokeWidth);
    
    if (mDaBox != null) {
      if (android.os.Build.VERSION.SDK_INT < 16) {
        mDaBox.setBackgroundDrawable(mCropDrawable);
      } else {
        mDaBox.setBackground(mCropDrawable);
      }
    }
  }
  
  public void setImageResource(Resources resources, int resId) {
    this.setImageBitmap(BitmapFactory.decodeResource(getResources(), resId));
  }
  
  public Bitmap crop(Context context) throws IllegalArgumentException {
    // Weird padding cause image size
    int weirdSidePadding = this.getWeirdSideMargin();
    int weirdVerticalPadding = this.getWeirdVerticalMargin();
    
    FrameLayout.LayoutParams params = (LayoutParams) mDaBox.getLayoutParams();
    
    // Getting crop dimensions
    float d = context.getResources().getDisplayMetrics().density;
    int x = (int)((params.leftMargin - weirdSidePadding) * d);
    int y = (int)((params.topMargin - weirdVerticalPadding) * d);
    int width = (int)((this.getWidth() - params.leftMargin - params.rightMargin) * d);
    int height = (int)((this.getHeight() - params.topMargin - params.bottomMargin) * d);
    
    Bitmap crooopppppppppppppppeed = Bitmap.createBitmap(mBitmap, x, y, width, height);
    
    return crooopppppppppppppppeed;
  }
  
  private void init() {
    mDraggerDrawable = this.getCircleDrawable(Color.rgb(255, 200, 0), HEIGHT_OF_DRAGGER, HEIGHT_OF_DRAGGER);
    mCropDrawable = this.getCropDrawable(Color.LTGRAY, 150, Color.LTGRAY, 255, 8);
    
    if (mImageView == null) {
      mImageView = new ImageView(this.getContext());
      
      FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
      this.addView(mImageView, params);
    }
    
  }
  
  @Override
  protected void onLayout( boolean changed, int left, int top, int right, int bottom ) {
    super.onLayout(changed, left, top, right, bottom);
    
    if (mTopLeftDragger == null) {
      mTopLeftDragger = new ImageView(this.getContext());
      mTopLeftDragger.setImageDrawable(mDraggerDrawable);
      mTopLeftDragger.setOnTouchListener(this);
      
      FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
      params.setMargins(INITIAL_MARGIN_OF_DRAGGER, INITIAL_MARGIN_OF_DRAGGER, 0, 0);
      this.addView(mTopLeftDragger, params);
    }
    
    if (mBottomRightDragger == null) {
      mBottomRightDragger = new ImageView(this.getContext());
      mBottomRightDragger.setImageDrawable(mDraggerDrawable);
      mBottomRightDragger.setOnTouchListener(this);
      
      int width = this.getWidth();
      int height = this.getHeight();
      
      int leftMargin = width - INITIAL_MARGIN_OF_DRAGGER - HEIGHT_OF_DRAGGER;
      int topMargin = height - INITIAL_MARGIN_OF_DRAGGER - HEIGHT_OF_DRAGGER;
      int rightMargin = 0;
      int bottomMargin = 0;
      
      if (mKeepSquare) {
        int smallestMargin = Math.min(leftMargin, topMargin);
        leftMargin = smallestMargin;
        topMargin = smallestMargin;
      }
      
      FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
      params.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
      this.addView(mBottomRightDragger, params);
    }
    
    if (mDaBox == null) {
      mDaBox = new ImageView(this.getContext());
//      mDaBox.setImageDrawable(this.getCropDrawable());
      if (android.os.Build.VERSION.SDK_INT < 16) {
        mDaBox.setBackgroundDrawable(mCropDrawable);
      } else {
        mDaBox.setBackground(mCropDrawable);
      }
      mDaBox.setScaleType(ScaleType.MATRIX);
      mDaBox.setAdjustViewBounds(true);
      mDaBox.setOnTouchListener(this);
//      mDaBox.setBackgroundColor(Color.WHITE);
      
//      FrameLayout.LayoutParams paramsTopLeft = (LayoutParams) mTopLeftDragger.getLayoutParams();
//      FrameLayout.LayoutParams paramsBottomRight = (LayoutParams) mBottomRightDragger.getLayoutParams();
//      
//      int leftMargin = (int) (paramsTopLeft.leftMargin + (HEIGHT_OF_DRAGGER/2.0));
//      int topMargin = (int) (paramsTopLeft.topMargin + (HEIGHT_OF_DRAGGER/2.0));
//      int rightMargin = (int) (paramsBottomRight.rightMargin + HEIGHT_OF_DRAGGER + INITIAL_MARGIN_OF_DRAGGER);
//      int bottomMargin = (int) (paramsBottomRight.bottomMargin + HEIGHT_OF_DRAGGER + INITIAL_MARGIN_OF_DRAGGER);
//      
      FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
//      params.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
      this.addView(mDaBox, 1, params);
      
      moveCrop();
    }
  }
  
  FrameLayout.LayoutParams parms;
//  LinearLayout.LayoutParams par;
  float dx=0,dy=0,x=0,y=0;
  
  @Override
    public boolean onTouch(View v, MotionEvent event) {
    switch(event.getAction())
      {
          case MotionEvent.ACTION_DOWN :
          {
//            if (v == mTopLeftDragger || v == mBottomRightDragger) {
                parms = (LayoutParams) v.getLayoutParams();
                dx = event.getRawX() - parms.leftMargin;
                dy = event.getRawY() - parms.topMargin;
//            } else if (v == mDaBox) {
//              
//            }
          }
          break;
          case MotionEvent.ACTION_MOVE :
          {
              x = event.getRawX();
              y = event.getRawY();
              
              if (v == mTopLeftDragger || v == mBottomRightDragger) {
                int leftMargin = (int) (x-dx);
                int topMargin = (int) (y - dy);
                
            if (mKeepSquare) {
              int dLeft = leftMargin - parms.leftMargin;
                  int dTop = topMargin - parms.topMargin;
              
              int smallestMargin = Math.min(dLeft, dTop);
              leftMargin = smallestMargin;
              topMargin = smallestMargin;
              
              parms.leftMargin += smallestMargin;
                  parms.topMargin += smallestMargin;
            } else {
              parms.leftMargin = leftMargin;
                  parms.topMargin = topMargin;
            }
                
                
                v.setLayoutParams(parms);
                
                moveCrop();
              } else if (v == mDaBox) {
                int leftMargin = (int) (x-dx);
                int topMargin = (int) (y - dy);
                
                int dLeft = leftMargin - parms.leftMargin;
                int dTop = topMargin - parms.topMargin;
                
                parms.leftMargin = leftMargin;
                parms.topMargin = topMargin;
                parms.rightMargin -= dLeft;
                parms.bottomMargin -= dTop;
                v.setLayoutParams(parms);
                
                FrameLayout.LayoutParams topLeftParams = (LayoutParams) mTopLeftDragger.getLayoutParams();
                topLeftParams.leftMargin += dLeft;
                topLeftParams.topMargin += dTop;
                mTopLeftDragger.setLayoutParams(topLeftParams);
                
                FrameLayout.LayoutParams bottomRightParams = (LayoutParams) mBottomRightDragger.getLayoutParams();
                bottomRightParams.leftMargin += dLeft;
                bottomRightParams.topMargin += dTop;
                mBottomRightDragger.setLayoutParams(bottomRightParams);
            }
          }
          break;
          case MotionEvent.ACTION_UP :
          {

          }
          break;
      }
      return true;
    }

  private void moveCrop() {
    FrameLayout.LayoutParams paramsTopLeft = (LayoutParams) mTopLeftDragger.getLayoutParams();
    FrameLayout.LayoutParams paramsBottomRight = (LayoutParams) mBottomRightDragger.getLayoutParams();
    
    int width = this.getWidth();
    int height = this.getHeight();
    
    int widthOfCorner = mDraggerDrawable.getIntrinsicWidth();
    int heightOfCorner = mDraggerDrawable.getIntrinsicHeight();
    
    int leftMargin = (int) (paramsTopLeft.leftMargin + (widthOfCorner/2.0f));
    int topMargin = (int) (paramsTopLeft.topMargin + (heightOfCorner/2.0f));
    int rightMargin = (int) (width - paramsBottomRight.leftMargin - (widthOfCorner/2.0f));
    int bottomMargin = (int) (height - paramsBottomRight.topMargin - (heightOfCorner/2.0f));
    
    FrameLayout.LayoutParams params = (LayoutParams) mDaBox.getLayoutParams();;
    params.leftMargin = leftMargin;
    params.topMargin = topMargin;
    params.rightMargin = rightMargin;
    params.bottomMargin = bottomMargin;
    mDaBox.setLayoutParams(params);

  }
  
  private Drawable getCircleDrawable(int color, int width, int height) {
        ShapeDrawable biggerCircle= new ShapeDrawable( new OvalShape());
        biggerCircle.setIntrinsicWidth( width);
        biggerCircle.setIntrinsicHeight( height );
        biggerCircle.setBounds(new Rect(0, 0, width, height));
        biggerCircle.getPaint().setColor(color);
        
        return biggerCircle;
  }
  
  private Drawable getCropDrawable(int fillColor, int fillAlpha, int strokeColor, int strokeAlpha, int strokeWidth) {
    ShapeDrawable sd1 = new ShapeDrawable(new RectShape());
    sd1.getPaint().setColor(strokeColor);
    sd1.getPaint().setStyle(Style.STROKE);
    sd1.getPaint().setStrokeWidth(strokeWidth);
    sd1.setAlpha(255);
     
    ShapeDrawable sd2 = new ShapeDrawable(new RectShape());
    sd2.getPaint().setColor(fillColor);
    sd2.getPaint().setStyle(Style.FILL);
    sd2.setAlpha(fillAlpha);
     
    Drawable[] layers = new Drawable[2];
    layers[0] = sd1;
    layers[1] = sd2;
    LayerDrawable composite = new LayerDrawable(layers);
    
    return composite;
  }
  
  private int getWeirdSideMargin() {
    // Weird padding cause image size
    int weirdSidePadding = 0;
    
    // Image width / height ration
    double bitmapRatio = ((double)mBitmap.getWidth() / (double)mBitmap.getHeight());
    
    // Image width / height ration
    double thisRatio = ((double)this.getWidth() / (double)this.getHeight());

    // Magic math
    if (bitmapRatio < thisRatio) {
      int bitmapWidth = (int) (bitmapRatio * this.getHeight());
      weirdSidePadding = (int) ((this.getWidth() - bitmapWidth) / 2.0); 
    } else {
      
    }
    
    return weirdSidePadding;
  }
  
  private int getWeirdVerticalMargin() {
    // Weird padding cause image size
    int weirdVerticalPadding = 0;
    
    // Image width / height ration
    double bitmapRatio = ((double)mBitmap.getWidth() / (double)mBitmap.getHeight());
    
    // Image width / height ration
    double thisRatio = ((double)this.getWidth() / (double)this.getHeight());

    // Magic math
    if (bitmapRatio < thisRatio) {
 
    } else {
      int bitmapHeight = (int) (bitmapRatio * this.getWidth());
      weirdVerticalPadding = (int) ((this.getHeight() - bitmapHeight) / 2.0);
    }
    
    return weirdVerticalPadding;
  }
  
}




Java Source Code List

com.joshholtz.cropimageview.CropImageView.java