Подтвердить что ты не робот

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

Ответ 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" />