为了账号安全,请及时绑定邮箱和手机立即绑定

Android图像视图捏缩放

Android图像视图捏缩放

PIPIONE 2019-11-25 14:35:30
我正在使用Makeing Sense of Multitouch中的代码示例 来缩放图像视图。在ScaleListener上,我添加ScaleGestureDetector.getFocusX() and getFocusY()了内容以缩放手势的焦点。一切正常。问题是,在第一次多点触摸时,整个图像绘制位置都将更改为当前接触点,并从此处进行缩放。您能帮我解决这个问题吗?这是我的TouchImageView代码示例。以及我在活动中如何使用它。ImageView imageView = (ImageView) findViewById(R.id.imgView);int hMargin = (int) (displayMetrics.widthPixels * .10);int vMargin = (int) (displayMetrics.heightPixels * .10);RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(displayMetrics.widthPixels - (hMargin * 2), (int)(displayMetrics.heightPixels - btnCamera.getHeight()) - (vMargin * 2));params.leftMargin = hMargin;params.topMargin =  vMargin;imageView.setLayoutParams(params);imageView.setImageDrawable(drawable);
查看完整描述

3 回答

?
慕姐4208626

TA贡献1852条经验 获得超7个赞

我捏捏缩放以制作自己的自定义图像视图。Chirag Raval的代码没有限制/限制,因此用户可以将图像拖出屏幕。这将解决它。


这是CustomImageView类:


    public class CustomImageVIew extends ImageView implements OnTouchListener {



    private Matrix matrix = new Matrix();

    private Matrix savedMatrix = new Matrix();


    static final int NONE = 0;

    static final int DRAG = 1;

    static final int ZOOM = 2;


    private int mode = NONE;


    private PointF mStartPoint = new PointF();

    private PointF mMiddlePoint = new PointF();

    private Point mBitmapMiddlePoint = new Point();


    private float oldDist = 1f;

    private float matrixValues[] = {0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f};

    private float scale;

    private float oldEventX = 0;

    private float oldEventY = 0;

    private float oldStartPointX = 0;

    private float oldStartPointY = 0;

    private int mViewWidth = -1;

    private int mViewHeight = -1;

    private int mBitmapWidth = -1;

    private int mBitmapHeight = -1;

    private boolean mDraggable = false;



    public CustomImageVIew(Context context) {

        this(context, null, 0);

    }


    public CustomImageVIew(Context context, AttributeSet attrs) {

        this(context, attrs, 0);

    }


    public CustomImageVIew(Context context, AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);

        this.setOnTouchListener(this);

    }


    @Override

    public void onSizeChanged (int w, int h, int oldw, int oldh){

        super.onSizeChanged(w, h, oldw, oldh);

        mViewWidth = w;

        mViewHeight = h;

    }


    public void setBitmap(Bitmap bitmap){

        if(bitmap != null){

            setImageBitmap(bitmap);


            mBitmapWidth = bitmap.getWidth();

            mBitmapHeight = bitmap.getHeight();

            mBitmapMiddlePoint.x = (mViewWidth / 2) - (mBitmapWidth /  2);

            mBitmapMiddlePoint.y = (mViewHeight / 2) - (mBitmapHeight / 2);


            matrix.postTranslate(mBitmapMiddlePoint.x, mBitmapMiddlePoint.y);

            this.setImageMatrix(matrix);

        }

    }


    @Override

    public boolean onTouch(View v, MotionEvent event){

        switch (event.getAction() & MotionEvent.ACTION_MASK) {

        case MotionEvent.ACTION_DOWN:

            savedMatrix.set(matrix);

            mStartPoint.set(event.getX(), event.getY());

            mode = DRAG;

            break;

        case MotionEvent.ACTION_POINTER_DOWN:

            oldDist = spacing(event);

            if(oldDist > 10f){

                savedMatrix.set(matrix);

                midPoint(mMiddlePoint, event);

                mode = ZOOM;

            }

            break;

        case MotionEvent.ACTION_UP:

        case MotionEvent.ACTION_POINTER_UP:

            mode = NONE;

            break;

        case MotionEvent.ACTION_MOVE:

            if(mode == DRAG){

                drag(event);

            } else if(mode == ZOOM){

                zoom(event);

            } 

            break;

        }


        return true;

    }




   public void drag(MotionEvent event){

       matrix.getValues(matrixValues);


       float left = matrixValues[2];

       float top = matrixValues[5];

       float bottom = (top + (matrixValues[0] * mBitmapHeight)) - mViewHeight;

       float right = (left + (matrixValues[0] * mBitmapWidth)) -mViewWidth;


       float eventX = event.getX();

       float eventY = event.getY();

       float spacingX = eventX - mStartPoint.x;

       float spacingY = eventY - mStartPoint.y;

       float newPositionLeft = (left  < 0 ? spacingX : spacingX * -1) + left;

       float newPositionRight = (spacingX) + right;

       float newPositionTop = (top  < 0 ? spacingY : spacingY * -1) + top;

       float newPositionBottom = (spacingY) + bottom;

       boolean x = true;

       boolean y = true;


       if(newPositionRight < 0.0f || newPositionLeft > 0.0f){

           if(newPositionRight < 0.0f && newPositionLeft > 0.0f){

               x = false;

           } else{

               eventX = oldEventX;

               mStartPoint.x = oldStartPointX;

           }

       }

       if(newPositionBottom < 0.0f || newPositionTop > 0.0f){

           if(newPositionBottom < 0.0f && newPositionTop > 0.0f){

               y = false;

           } else{

               eventY = oldEventY;

               mStartPoint.y = oldStartPointY;

           }

       }


       if(mDraggable){

           matrix.set(savedMatrix);

           matrix.postTranslate(x? eventX - mStartPoint.x : 0, y? eventY - mStartPoint.y : 0);

           this.setImageMatrix(matrix);

           if(x)oldEventX = eventX;

           if(y)oldEventY = eventY;

           if(x)oldStartPointX = mStartPoint.x;

           if(y)oldStartPointY = mStartPoint.y;

       }


   }


   public void zoom(MotionEvent event){

       matrix.getValues(matrixValues);


       float newDist = spacing(event);

       float bitmapWidth = matrixValues[0] * mBitmapWidth;

       float bimtapHeight = matrixValues[0] * mBitmapHeight;

       boolean in = newDist > oldDist;


       if(!in && matrixValues[0] < 1){

           return;

       }

       if(bitmapWidth > mViewWidth || bimtapHeight > mViewHeight){

           mDraggable = true;

       } else{

           mDraggable = false;

       }


       float midX = (mViewWidth / 2);

       float midY = (mViewHeight / 2);


       matrix.set(savedMatrix);

       scale = newDist / oldDist;

       matrix.postScale(scale, scale, bitmapWidth > mViewWidth ? mMiddlePoint.x : midX, bimtapHeight > mViewHeight ? mMiddlePoint.y : midY); 


       this.setImageMatrix(matrix);



   }






    /** Determine the space between the first two fingers */

    private float spacing(MotionEvent event) {

        float x = event.getX(0) - event.getX(1);

        float y = event.getY(0) - event.getY(1);


        return (float)Math.sqrt(x * x + y * y);

    }


    /** Calculate the mid point of the first two fingers */

    private void midPoint(PointF point, MotionEvent event) {

        float x = event.getX(0) + event.getX(1);

        float y = event.getY(0) + event.getY(1);

        point.set(x / 2, y / 2);

    }



}

这是在活动中使用它的方式:


CustomImageVIew mImageView = (CustomImageVIew)findViewById(R.id.customImageVIew1);

mImage.setBitmap(your bitmap);

和布局:


<your.package.name.CustomImageVIew

        android:id="@+id/customImageVIew1"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:layout_marginBottom="15dp"

        android:layout_marginLeft="15dp"

        android:layout_marginRight="15dp"

        android:layout_marginTop="15dp"

        android:layout_centerHorizontal="true"

        android:layout_centerVertical="true" 

        android:scaleType="matrix"/> // important


查看完整回答
反对 回复 2019-11-25
?
繁星coding

TA贡献1797条经验 获得超4个赞

在build.gradle中添加以下行:


compile 'com.commit451:PhotoView:1.2.4'

要么


compile 'com.github.chrisbanes:PhotoView:1.3.0'

在Java文件中:


PhotoViewAttacher photoAttacher;

photoAttacher= new PhotoViewAttacher(Your_Image_View);

photoAttacher.update();


查看完整回答
反对 回复 2019-11-25
  • 3 回答
  • 0 关注
  • 350 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信