2015-08-17 5 views
14

Я создаю приложение, в котором пользователь сможет щелкнуть часть изображения и получить увеличенную версию в углу WebView. Мне удалось создать Paint, который сделает версию масштабирования, но отображает неправильное местоположение, например, есть смещение.Как увеличить/увеличить часть изображения

Я знаю, что этот вопрос задан много раз и уже был дан ответ, но, похоже, не помогли эти решения.

Вот код, который я использовал:

@Override 
     public boolean onTouchEvent(@NonNull MotionEvent event) { 
      zoomPos = new PointF(); 
      zoomPos.x = event.getX(); 
      zoomPos.y = event.getY(); 


     matrix = new Matrix(); 
     mShader = new BitmapShader(MainActivity.mutableBitmap, TileMode.CLAMP, TileMode.CLAMP); 
     mPaint = new Paint(); 
     mPaint.setShader(mShader); 
     outlinePaint = new Paint(Color.BLACK); 
     outlinePaint.setStyle(Paint.Style.STROKE); 

     int action = event.getAction(); 

     switch (action) { 
     case MotionEvent.ACTION_DOWN: 
     case MotionEvent.ACTION_MOVE: 
      zooming = true; 
      this.invalidate(); 
      break; 
     case MotionEvent.ACTION_UP: 
      Point1 = true; 
      zooming = false; 
      this.invalidate(); 
      break; 
     case MotionEvent.ACTION_CANCEL: 
      zooming = false; 
      this.invalidate(); 
      break; 

     default: 
      break; 
     } 



    return true; 
    } 

    @Override 
    protected void onDraw(@NonNull Canvas canvas) { 
     super.onDraw(canvas); 
     if (zooming) { 
      matrix.reset(); 
      matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y); 
      mPaint.getShader().setLocalMatrix(matrix); 


      canvas.drawCircle(100, 100, 100, mPaint); 

     } 

    } 

Технически он должен нарисовать круг в верхнем левом углу и отобразить увеличенное изображение в области, где мой палец, он рисует круг, но опять же, зум сдвинуты.

Окончательный результат должен выглядеть примерно так:

enter image description here

MainActivity.java

public class MainActivity extends Activity { 
static ImageView takenPhoto; 
static PointF zoomPos; 
Paint shaderPaint; 
static BitmapShader mShader; 
BitmapShader shader; 
Bitmap bmp; 
static Bitmap mutableBitmap; 
static Matrix matrix; 
Canvas canvas; 
static Paint mPaint; 
static Paint Paint; 
static boolean zooming; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     File file = new File(Environment.getExternalStorageDirectory() + "/Pictures/boxes.jpg"); 

     String fileString = file.getPath(); 
     takenPhoto = (ZoomView) findViewById(R.id.imageView1); 
     bmp = BitmapFactory.decodeFile(fileString); 
     mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true); 
     takenPhoto.setImageBitmap(mutableBitmap);  
     matrix = new Matrix(); 
     mShader = new BitmapShader(mutableBitmap, TileMode.CLAMP, TileMode.CLAMP); 
     mPaint = new Paint(); 
     mPaint.setShader(mShader); 
     zoomPos = new PointF(); 
     Paint = new Paint(Color.RED); 
    } 
} 

ZoomView.java

public class ZoomView extends ImageView { 

    private PointF zoomPos; 
    PointF fingerPos; 
    private Paint paint = new Paint(Color.BLACK); 
    boolean zooming; 
    Matrix matrix; 
    BitmapShader mShader; 
    Paint mPaint; 
    Paint outlinePaint; 
    boolean Point1; 

    public ZoomView(Context context) { 
     super(context); 
    } 

    public ZoomView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public ZoomView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @Override 
    public boolean onTouchEvent(@NonNull MotionEvent event) { 
     zoomPos = new PointF(); 
     zoomPos.x = event.getX(); 
     zoomPos.y = event.getY(); 


     matrix = new Matrix(); 
     mShader = new BitmapShader(MainActivity.mutableBitmap, TileMode.CLAMP, TileMode.CLAMP); 
     mPaint = new Paint(); 
     mPaint.setShader(mShader); 
     outlinePaint = new Paint(Color.BLACK); 
     outlinePaint.setStyle(Paint.Style.STROKE); 

     int action = event.getAction(); 

     switch (action) { 
     case MotionEvent.ACTION_DOWN: 
     case MotionEvent.ACTION_MOVE: 
      zooming = true; 
      this.invalidate(); 
      break; 
     case MotionEvent.ACTION_UP: 
      Point1 = true; 
      zooming = false; 
      this.invalidate(); 
      break; 
     case MotionEvent.ACTION_CANCEL: 
      zooming = false; 
      this.invalidate(); 
      break; 

     default: 
      break; 
     } 



    return true; 
    } 

    @Override 
    protected void onDraw(@NonNull Canvas canvas) { 
     super.onDraw(canvas); 
     if (zooming) { 
      matrix.reset(); 
     matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y); 
     mPaint.getShader().setLocalMatrix(matrix); 
     RectF src = new RectF(zoomPos.x-50, zoomPos.y-50, zoomPos.x+50, zoomPos.y+50); 
     RectF dst = new RectF(0, 0, 100, 100); 
     matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER); 
     matrix.postScale(2f, 2f); 
     mPaint.getShader().setLocalMatrix(matrix); 


     canvas.drawCircle(100, 100, 100, mPaint); 
     canvas.drawCircle(zoomPos.x, zoomPos.y, 100, mPaint); 
     canvas.drawCircle(zoomPos.x-110, zoomPos.y-110, 10, outlinePaint); 

     } 
     if(Point1){ 
      canvas.drawCircle(zoomPos.x, zoomPos.y, 10, paint); 
     } 
    } 
} 

EDIT:

Как вы можете видеть, новый код лучше, все еще есть какая-то смещение - черная точка - положение пальца.

enter image description here

+0

Bump this thing –

+0

У меня трудное понимание _exactly_, что вы просите, но вот несколько указателей для вас: вы можете быть неправильно настроены из-за того, что ваше трогательное местоположение является левым верхним углом, подумайте об использовании getSize на MotionEvent, чтобы обнаруживать жирные штрихи и размещать себя посередине. Во-вторых, вам может понадобиться изучить getRawX/getRawY, если вам требуется исходное (экранное) местоположение касаний. – JohanShogun

+0

Это очень похожий вопрос на мой вопрос, может быть, он что-то прояснит для вас [http://stackoverflow.com/questions/13864480/android-how-to-circular-zoom-magnify-part-of-image) , Фактически, я использовал его для создания своего кода. Проблема в том, что он отображает неправильное местоположение. –

ответ

6

Кажется, что проблема с тем, как вы используете matrix.

Теперь вы используете оригинальное изображение (1) как шейдер, который затем будучи после масштабируется вокруг точки поворота (2), которая, как делает масштабирование вокруг точки (3) - но не центрирование точки (4)! (Например, открытые карты Google и увеличить масштаб карты с помощью мыши - точка масштабируется вокруг оси, но ось не по центру)

enter image description here

Что будет более простой способ добиться того, что вы хотите использовать Rect до Rectmethod. И.Е. вы хотите взять небольшую площадь от исходного изображения (5) и нарисовать его в большую область (6).

enter image description here

А вот пример кода:

RectF src = new RectF(zoomPos.x-50, zoomPos.y-50, zoomPos.x+50, zoomPos.y+50); 
RectF dst = new RectF(0, 0, 200, 200); 
matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER); 

Некоторые больше очков:

  • Старайтесь не создавать new объект в onTouch - она ​​вызывается много раз и это не хорошо на производительность. Вместо этого создайте один раз и повторно используйте.
  • getAction() будет иметь проблемы при наличии более одного пальца на экране, так как это идентификатор действия и идентификатор указателя. Вместо этого используйте getActionMasked() и getActionIndex().
  • Не используйте жестко заданные значения (50/100 в примере кода) - это пиксели и не знают о плотности экрана. Используйте масштабный размер, например dp.
+0

Я обновил свой ZoomView. Теперь в области углов отобразится круг, который я касаюсь, но он не масштабируется. –

+0

Скорее всего, это связано с тем, что 'src' и' dst' 'RectF' имеют одинаковые размеры. Сделайте «src» меньше, или «dst» больше для эффекта масштабирования. – JHobern

+0

Действительно, я редактировал код - целевой прямоугольник должен быть больше. В образце X2 больше. (был X1, поэтому у вас не было увеличения) –

Смежные вопросы