Выберите часть изображения в ImageView и найдите конечные точки выбранного прямоугольника

Мне нужно перетащить и выбрать часть изображения, установленного в ImageView и получить конечные точки выбранного прямоугольника без каких-либо изменений (например, обрезки).

Пока все, что я смог сделать, это выяснить координаты точки, в которой пользователь забирает экран.

 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; } }); 

Но это далеко от того, где я хочу быть. И я действительно не смог найти ничего связанного с StackOverFlow / Google.

Как я могу его реализовать?

Вот один из способов, который вы можете использовать (однако есть много возможностей реализовать то же самое). Он основан на создании пользовательского представления для рисования и отслеживания прямоугольника выделения. Кроме того, вы можете просто применить логику из onTouch() пользовательского представления в OnTouchListener() .

Основной макет:

 <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> 

Пользовательский вид:

 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(mEndY, mStartX))); } 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); } } } 

Активность проста:

 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(); } }); } } } 

Вывод выглядит следующим образом:

образ

Я просто попробовал ваше решение, это довольно круто. Возможно, я ошибаюсь, но я думаю, что в вашем продукте Toast есть опечатка:

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

должно быть:

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

В противном случае значение дна иногда вычисляется неправильно.

Другой способ: https://github.com/edmodo/cropper

Из документа Doc:

Cropper – инструмент для обрезки изображения. Он обеспечивает способ установки изображения в формате XML и программно и отображает окно масштабируемого урожая поверх изображения. Вызов метода getCroppedImage () затем возвращает растровое изображение, отмеченное окном обрезки.

Разработчики могут настраивать следующие атрибуты (как через XML, так и программно):

Появление руководящих принципов в окне обрезки, независимо от того, фиксировано ли соотношение сторон или нет пропорции (если соотношение сторон фиксировано) ресурс изображения. Также включен общедоступный метод поворота изображения с заданным количеством градусов. Это можно использовать, чтобы предоставить пользователю возможность исправить ориентацию изображения, если Android не рассчитает предполагаемую ориентацию.

Поддерживается на уровне API 7 и выше.

Для получения дополнительной информации см. Связанную страницу Github Wiki.

Intereting Posts
Файл Android.bat отсутствует в папке sdk \ tools, также у меня нет менеджера AVD и SDK в инструментах, поэтому я могу их заменить CrossWalk XWalkView (альтернатива Webview) не работает с AppBarLayout + CoordinatorLayout OpenGL 2.0 или выше с расширением FBO – LibGDX Error False «Генерировать подписанные APK – APK (s) сгенерированы успешно» всплывающее сообщение при каждом создании сборки (после создания подписанного apk один раз) Libavcodec.so: имеет перемещение текста «Цвет фона Android» случайно изменен Как запустить существующий экземпляр действия, когда он запускается из статического ярлыка Получить имя шрифта из файла из папки с ресурсами Эмулятор зависает при загрузке анимации Ожидается запуск HOME ('android.process.acore') Пинч-зум для пользовательского просмотра Социальный знак в приложении Android / iPhone со стороны сервера Включать один и тот же макет несколько раз Как рассчитать размер библиотек, добавленных как зависимость в проекте Android Преобразование объекта в JSON на Android Как установить пользовательскую дату в android