Android - Как круговое масштабирование/увеличение части изображения?
Я пытаюсь дозволить пользователю коснуться изображения, а затем, в основном, увеличить круговую лупу, что позволит пользователю лучше выбрать определенную область на изображении. Когда пользователь отпускает прикосновение, увеличенная часть будет исчезать. Это используется в нескольких приложениях для редактирования фотографий, и я пытаюсь реализовать свою собственную версию. Код, который у меня ниже, увеличивает круговую часть изображения, но не удаляет или не уменьшает масштаб после того, как я отпустил палец. В настоящее время я устанавливаю растровое изображение на холст с помощью canvas = new Canvas(bitMap);
, а затем устанавливаю изображение с помощью takenPhoto.setImageBitmap(bitMap);
. Я не уверен, правильно ли я это сделаю. Код onTouch находится ниже:
zoomPos = new PointF(0,0);
takenPhoto.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
zoomPos.x = event.getX();
zoomPos.y = event.getY();
matrix.reset();
matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
shader.setLocalMatrix(matrix);
canvas.drawCircle(zoomPos.x, zoomPos.y, 20, shaderPaint);
takenPhoto.invalidate();
break;
case MotionEvent.ACTION_MOVE:
zoomPos.x = event.getX();
zoomPos.y = event.getY();
matrix.reset();
matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
canvas.drawCircle(zoomPos.x, zoomPos.y, 20, shaderPaint);
takenPhoto.invalidate();
break;
case MotionEvent.ACTION_UP:
//clear zoom here?
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
});
Ответы
Ответ 1
Адаптировав свой код, я смог использовать следующий подход.
В функции onTouch задайте глобальную точку для определения того, где пользователь коснулся, и установите логическое значение, чтобы указать, активна ли масштабирование в настоящее время или нет:
@Override
public boolean onTouch(View view, MotionEvent event) {
int action = event.getAction();
zoomPos.x = event.getX();
zoomPos.y = event.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
zooming = true;
this.invalidate();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
zooming = false;
this.invalidate();
break;
default:
break;
}
return true;
}
Затем в методе onDraw вы используете свой код для рисования увеличенной части:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (zooming) {
matrix.reset();
matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
mPaint.getShader().setLocalMatrix(matrix);
canvas.drawCircle(zoomPos.x, zoomPos.y, 100, mPaint);
}
}
Обратите внимание, что для шейдера я использовал растровый шейдер, как описано здесь, который был создан с помощью
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
mShader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);
mPaint = new Paint();
mPaint.setShader(mShader);
Ответ 2
Лучший способ отменить любые изменения, сделанные на изображении, - это перезагрузить изображение из исходного файла. Или, наоборот, сохраните исходную матричную переменную копии перед началом преобразований, во время MotionEvent.ACTION_UP
загрузите исходную матрицу.
Ответ 3
Вы можете реализовать его, используя пользовательское изображение, создать класс CodesforMagnifierImageView.java в своем пакете. Вы можете увидеть код для соответствующего класса в CodesforMagnifier.java и просто использовать следующий код в своем файле макета вместо изображения
<com.yourpackage.CodesforMagnifierImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/your image" />