Select a portion of the image in ImageView and find the endpoints of the selected rectangle.

I need to drag and select the part of the image set in ImageView and get the end points of the selected rectangle without any changes (e.g. cropping).

So far, all I have managed to do is figure out the coordinates of the point at which the user clicks the screen.

 ImageView imageView = (ImageView) findViewById(R.id.imageView); imageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //Simply displays a toast Utilities.displayToast(getApplicationContext(), "Touch coordinates : " + String.valueOf(event.getX()) + "x" + String.valueOf(event.getY())); return true; } }); 

But this is far from where I want to be. And I really could not find anything related to StackOverFlow / Google.

How can I implement it?

+7
source share
3 answers

Here you can use one of the methods (however, there are many possibilities for implementing the same). It is based on creating your own view for drawing and tracking the selection of a rectangle. Alternatively, you can simply apply the logic from onTouch() user view to OnTouchListener() .

The main layout:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="match_parent" android:id="@+id/root" android:background="@android:color/background_dark"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/image" android:src="@drawable/up_image" android:scaleType="fitXY" /> <com.example.TestApp.DragRectView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/dragRect" /> </RelativeLayout> 

Custom view:

 import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.text.TextPaint; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class DragRectView extends View { private Paint mRectPaint; private int mStartX = 0; private int mStartY = 0; private int mEndX = 0; private int mEndY = 0; private boolean mDrawRect = false; private TextPaint mTextPaint = null; private OnUpCallback mCallback = null; public interface OnUpCallback { void onRectFinished(Rect rect); } public DragRectView(final Context context) { super(context); init(); } public DragRectView(final Context context, final AttributeSet attrs) { super(context, attrs); init(); } public DragRectView(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); init(); } /** * Sets callback for up * * @param callback {@link OnUpCallback} */ public void setOnUpCallback(OnUpCallback callback) { mCallback = callback; } /** * Inits internal data */ private void init() { mRectPaint = new Paint(); mRectPaint.setColor(getContext().getResources().getColor(android.R.color.holo_green_light)); mRectPaint.setStyle(Paint.Style.STROKE); mRectPaint.setStrokeWidth(5); // TODO: should take from resources mTextPaint = new TextPaint(); mTextPaint.setColor(getContext().getResources().getColor(android.R.color.holo_green_light)); mTextPaint.setTextSize(20); } @Override public boolean onTouchEvent(final MotionEvent event) { // TODO: be aware of multi-touches switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mDrawRect = false; mStartX = (int) event.getX(); mStartY = (int) event.getY(); invalidate(); break; case MotionEvent.ACTION_MOVE: final int x = (int) event.getX(); final int y = (int) event.getY(); if (!mDrawRect || Math.abs(x - mEndX) > 5 || Math.abs(y - mEndY) > 5) { mEndX = x; mEndY = y; invalidate(); } mDrawRect = true; break; case MotionEvent.ACTION_UP: if (mCallback != null) { mCallback.onRectFinished(new Rect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY), Math.max(mEndX, mStartX), Math.max(mStartY, mEndY))); } invalidate(); break; default: break; } return true; } @Override protected void onDraw(final Canvas canvas) { super.onDraw(canvas); if (mDrawRect) { canvas.drawRect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY), Math.max(mEndX, mStartX), Math.max(mEndY, mStartY), mRectPaint); canvas.drawText(" (" + Math.abs(mStartX - mEndX) + ", " + Math.abs(mStartY - mEndY) + ")", Math.max(mEndX, mStartX), Math.max(mEndY, mStartY), mTextPaint); } } } 

The activity is simple:

 public class MyActivity extends Activity { private static final String TAG = "MyActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final DragRectView view = (DragRectView) findViewById(R.id.dragRect); if (null != view) { view.setOnUpCallback(new DragRectView.OnUpCallback() { @Override public void onRectFinished(final Rect rect) { Toast.makeText(getApplicationContext(), "Rect is (" + rect.left + ", " + rect.top + ", " + rect.right + ", " + rect.bottom + ")", Toast.LENGTH_LONG).show(); } }); } } } 

The output is as follows:

image

+13
source

I just tried your solution, it's pretty cool. Maybe I'm wrong, but I think there is a typo in your Toast output:

 mCallback.onRectFinished(new Rect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY), Math.max(mEndX, mStartX), Math.max(mEndY, mStartX))); 

it should be:

 mCallback.onRectFinished(new Rect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY), Math.max(mEndX, mStartX), Math.max(mEndY, mStartY))); 

otherwise, the bottom value is sometimes calculated incorrectly.

+1
source

Another way: https://github.com/edmodo/cropper

From the doc doc:

Cropper is a cropping tool. This enables the image to be in XML format and programmatically, and also displays a mutable window culture on top of the image. Calling the getCroppedImage () method will then return the bitmap marked with the trim window.

Developers can customize the following attributes (both through XML and programmatically):

The appearance of the guidelines in the cropping window depends on whether the aspect ratio is fixed or not proportional to the aspect ratio (if the aspect ratio is fixed). An open method of image rotation by the specified number of degrees is also included. This can be used to provide the user with the ability to correct the orientation of the image if Android calculates the oriented orientation.

Supported at API level 7 and above.

See the related Github Wiki page for more information.

0
source

Source: https://habr.com/ru/post/953707/


All Articles