Note that there are some explanatory texts on larger screens.

plurals
  1. POCustom Android Image Crop
    primarykey
    data
    text
    <p>i just want to share this piece of code that i wrote. I tried searching for a custom crop activity, but most of them leads to the default "com.android.camera.action.CROP" despite the question custom crop, or freehand crop activity. Anyway, i just made one for myself, and hopefully it will help you guys.</p> <pre><code>public class CropView extends ImageView { Paint paint = new Paint(); private int initial_size = 300; private static Point leftTop, rightBottom, center, previous; private static final int DRAG= 0; private static final int LEFT= 1; private static final int TOP= 2; private static final int RIGHT= 3; private static final int BOTTOM= 4; private int imageScaledWidth,imageScaledHeight; // Adding parent class constructors public CropView(Context context) { super(context); initCropView(); } public CropView(Context context, AttributeSet attrs) { super(context, attrs, 0); initCropView(); } public CropView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initCropView(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(leftTop.equals(0, 0)) resetPoints(); canvas.drawRect(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y, paint); } @Override public boolean onTouchEvent(MotionEvent event) { int eventaction = event.getAction(); switch (eventaction) { case MotionEvent.ACTION_DOWN: previous.set((int)event.getX(), (int)event.getY()); break; case MotionEvent.ACTION_MOVE: if(isActionInsideRectangle(event.getX(), event.getY())) { adjustRectangle((int)event.getX(), (int)event.getY()); invalidate(); // redraw rectangle previous.set((int)event.getX(), (int)event.getY()); } break; case MotionEvent.ACTION_UP: previous = new Point(); break; } return true; } private void initCropView() { paint.setColor(Color.YELLOW); paint.setStyle(Style.STROKE); paint.setStrokeWidth(5); leftTop = new Point(); rightBottom = new Point(); center = new Point(); previous = new Point(); } public void resetPoints() { center.set(getWidth()/2, getHeight()/2); leftTop.set((getWidth()-initial_size)/2,(getHeight()-initial_size)/2); rightBottom.set(leftTop.x+initial_size, leftTop.y+initial_size); } private static boolean isActionInsideRectangle(float x, float y) { int buffer = 10; return (x&gt;=(leftTop.x-buffer)&amp;&amp;x&lt;=(rightBottom.x+buffer)&amp;&amp; y&gt;=(leftTop.y-buffer)&amp;&amp;y&lt;=(rightBottom.y+buffer))?true:false; } private boolean isInImageRange(PointF point) { // Get image matrix values and place them in an array float[] f = new float[9]; getImageMatrix().getValues(f); // Calculate the scaled dimensions imageScaledWidth = Math.round(getDrawable().getIntrinsicWidth() * f[Matrix.MSCALE_X]); imageScaledHeight = Math.round(getDrawable().getIntrinsicHeight() * f[Matrix.MSCALE_Y]); return (point.x&gt;=(center.x-(imageScaledWidth/2))&amp;&amp;point.x&lt;=(center.x+(imageScaledWidth/2))&amp;&amp;point.y&gt;=(center.y-(imageScaledHeight/2))&amp;&amp;point.y&lt;=(center.y+(imageScaledHeight/2)))?true:false; } private void adjustRectangle(int x, int y) { int movement; switch(getAffectedSide(x,y)) { case LEFT: movement = x-leftTop.x; if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement))) leftTop.set(leftTop.x+movement,leftTop.y+movement); break; case TOP: movement = y-leftTop.y; if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement))) leftTop.set(leftTop.x+movement,leftTop.y+movement); break; case RIGHT: movement = x-rightBottom.x; if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement))) rightBottom.set(rightBottom.x+movement,rightBottom.y+movement); break; case BOTTOM: movement = y-rightBottom.y; if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement))) rightBottom.set(rightBottom.x+movement,rightBottom.y+movement); break; case DRAG: movement = x-previous.x; int movementY = y-previous.y; if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movementY)) &amp;&amp; isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movementY))) { leftTop.set(leftTop.x+movement,leftTop.y+movementY); rightBottom.set(rightBottom.x+movement,rightBottom.y+movementY); } break; } } private static int getAffectedSide(float x, float y) { int buffer = 10; if(x&gt;=(leftTop.x-buffer)&amp;&amp;x&lt;=(leftTop.x+buffer)) return LEFT; else if(y&gt;=(leftTop.y-buffer)&amp;&amp;y&lt;=(leftTop.y+buffer)) return TOP; else if(x&gt;=(rightBottom.x-buffer)&amp;&amp;x&lt;=(rightBottom.x+buffer)) return RIGHT; else if(y&gt;=(rightBottom.y-buffer)&amp;&amp;y&lt;=(rightBottom.y+buffer)) return BOTTOM; else return DRAG; } public byte[] getCroppedImage() { BitmapDrawable drawable = (BitmapDrawable)getDrawable(); float x = leftTop.x-center.x+(drawable.getBitmap().getWidth()/2); float y = leftTop.y-center.y+(drawable.getBitmap().getHeight()/2); Bitmap cropped = Bitmap.createBitmap(drawable.getBitmap(),(int)x,(int)y,(int)rightBottom.x-(int)leftTop.x,(int)rightBottom.y-(int)leftTop.y); ByteArrayOutputStream stream = new ByteArrayOutputStream(); cropped.compress(Bitmap.CompressFormat.PNG, 100, stream); return stream.toByteArray(); } } </code></pre> <p>What i did was, i extended the ImageView and added Cropping powers. It is pretty easy to use. Once the class is saved, just use it in the layout like this.</p> <pre><code> &lt;"your package name".CropView android:id="@+id/image_preview" android:layout_width="fill_parent" android:layout_height="match_parent" /&gt; </code></pre> <p>Thats it! Hope it helps! If you encounter any problem, please feel free to ask :)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload