首页 文章

如何获得图像的缩放功能?

提问于
浏览
198

是否有一种常见的方式来显示大图像并使用户能够放大和缩小图像?

到现在为止我找到了两种方法:

  • 覆盖了ImageView,这对于这样一个常见问题来说似乎有点过分了 .

  • 使用webview但对整体布局等的控制较少

13 回答

  • 80

    更新

    我刚刚给TouchImageView一个新的更新 . 它现在包括双击缩放和Fling以及平移和缩放缩放 . 下面的代码非常过时 . 您可以查看github project以获取最新代码 .

    用法

    将TouchImageView.java放在项目中 . 然后它可以像ImageView一样使用 . 例:

    TouchImageView img = (TouchImageView) findViewById(R.id.img);
    

    如果您在xml中使用TouchImageView,则必须提供完整的包名称,因为它是自定义视图 . 例:

    <com.example.touch.TouchImageView
        android:id="@+id/img”
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    

    注意:我已经删除了我之前的答案,其中包括一些非常旧的代码,现在直接链接到github上最新的代码 .

    ViewPager

    如果您有兴趣将TouchImageView放入ViewPager,refer to this answer.

  • 206

    我调整了一些代码来创建支持多点触控(> 2.1)的TouchImageView . 它的灵感来自于书Hello, Android! (3rd edition)

    它包含在以下3个文件中TouchImageView.java WrapMotionEvent.java EclairMotionEvent.java

    TouchImageView.java

    import se.robertfoss.ChanImageBrowser.Viewer;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Matrix;
    import android.graphics.PointF;
    import android.util.FloatMath;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.ImageView;
    
    public class TouchImageView extends ImageView {
    
        private static final String TAG = "Touch";
        // These matrices will be used to move and zoom image
        Matrix matrix = new Matrix();
        Matrix savedMatrix = new Matrix();
    
        // We can be in one of these 3 states
        static final int NONE = 0;
        static final int DRAG = 1;
        static final int ZOOM = 2;
        int mode = NONE;
    
        // Remember some things for zooming
        PointF start = new PointF();
        PointF mid = new PointF();
        float oldDist = 1f;
    
        Context context;
    
    
        public TouchImageView(Context context) {
            super(context);
            super.setClickable(true);
            this.context = context;
    
            matrix.setTranslate(1f, 1f);
            setImageMatrix(matrix);
            setScaleType(ScaleType.MATRIX);
    
            setOnTouchListener(new OnTouchListener() {
    
                @Override
                public boolean onTouch(View v, MotionEvent rawEvent) {
                    WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent);
    
                    // Dump touch event to log
                    if (Viewer.isDebug == true){
                        dumpEvent(event);
                    }
    
                    // Handle touch events here...
                    switch (event.getAction() & MotionEvent.ACTION_MASK) {
                    case MotionEvent.ACTION_DOWN:
                        savedMatrix.set(matrix);
                        start.set(event.getX(), event.getY());
                        Log.d(TAG, "mode=DRAG");
                        mode = DRAG;
                        break;
                    case MotionEvent.ACTION_POINTER_DOWN:
                        oldDist = spacing(event);
                        Log.d(TAG, "oldDist=" + oldDist);
                        if (oldDist > 10f) {
                            savedMatrix.set(matrix);
                            midPoint(mid, event);
                            mode = ZOOM;
                            Log.d(TAG, "mode=ZOOM");
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        int xDiff = (int) Math.abs(event.getX() - start.x);
                        int yDiff = (int) Math.abs(event.getY() - start.y);
                        if (xDiff < 8 && yDiff < 8){
                            performClick();
                        }
                    case MotionEvent.ACTION_POINTER_UP:
                        mode = NONE;
                        Log.d(TAG, "mode=NONE");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (mode == DRAG) {
                            // ...
                            matrix.set(savedMatrix);
                            matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
                        } else if (mode == ZOOM) {
                            float newDist = spacing(event);
                            Log.d(TAG, "newDist=" + newDist);
                            if (newDist > 10f) {
                                matrix.set(savedMatrix);
                                float scale = newDist / oldDist;
                                matrix.postScale(scale, scale, mid.x, mid.y);
                            }
                        }
                        break;
                    }
    
                    setImageMatrix(matrix);
                    return true; // indicate event was handled
                }
    
            });
        }
    
    
        public void setImage(Bitmap bm, int displayWidth, int displayHeight) { 
            super.setImageBitmap(bm);
    
            //Fit to screen.
            float scale;
            if ((displayHeight / bm.getHeight()) >= (displayWidth / bm.getWidth())){
                scale =  (float)displayWidth / (float)bm.getWidth();
            } else {
                scale = (float)displayHeight / (float)bm.getHeight();
            }
    
            savedMatrix.set(matrix);
            matrix.set(savedMatrix);
            matrix.postScale(scale, scale, mid.x, mid.y);
            setImageMatrix(matrix);
    
    
            // Center the image
            float redundantYSpace = (float)displayHeight - (scale * (float)bm.getHeight()) ;
            float redundantXSpace = (float)displayWidth - (scale * (float)bm.getWidth());
    
            redundantYSpace /= (float)2;
            redundantXSpace /= (float)2;
    
    
            savedMatrix.set(matrix);
            matrix.set(savedMatrix);
            matrix.postTranslate(redundantXSpace, redundantYSpace);
            setImageMatrix(matrix);
        }
    
    
        /** Show an event in the LogCat view, for debugging */
        private void dumpEvent(WrapMotionEvent event) {
            // ...
            String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
                "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
            StringBuilder sb = new StringBuilder();
            int action = event.getAction();
            int actionCode = action & MotionEvent.ACTION_MASK;
            sb.append("event ACTION_").append(names[actionCode]);
            if (actionCode == MotionEvent.ACTION_POINTER_DOWN
                    || actionCode == MotionEvent.ACTION_POINTER_UP) {
                sb.append("(pid ").append(
                        action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
                sb.append(")");
            }
            sb.append("[");
            for (int i = 0; i < event.getPointerCount(); i++) {
                sb.append("#").append(i);
                sb.append("(pid ").append(event.getPointerId(i));
                sb.append(")=").append((int) event.getX(i));
                sb.append(",").append((int) event.getY(i));
                if (i + 1 < event.getPointerCount())
                sb.append(";");
            }
            sb.append("]");
            Log.d(TAG, sb.toString());
        }
    
        /** Determine the space between the first two fingers */
        private float spacing(WrapMotionEvent event) {
            // ...
            float x = event.getX(0) - event.getX(1);
            float y = event.getY(0) - event.getY(1);
            return FloatMath.sqrt(x * x + y * y);
        }
    
        /** Calculate the mid point of the first two fingers */
        private void midPoint(PointF point, WrapMotionEvent event) {
            // ...
            float x = event.getX(0) + event.getX(1);
            float y = event.getY(0) + event.getY(1);
            point.set(x / 2, y / 2);
        }
    }
    

    WrapMotionEvent.java

    import android.view.MotionEvent;
    
    public class WrapMotionEvent {
    protected MotionEvent event;
    
    
    
    
        protected WrapMotionEvent(MotionEvent event) {
            this.event = event;
        }
    
        static public WrapMotionEvent wrap(MotionEvent event) {
                try {
                    return new EclairMotionEvent(event);
                } catch (VerifyError e) {
                    return new WrapMotionEvent(event);
                }
        }
    
    
    
        public int getAction() {
                return event.getAction();
        }
    
        public float getX() {
                return event.getX();
        }
    
        public float getX(int pointerIndex) {
                verifyPointerIndex(pointerIndex);
                return getX();
        }
    
        public float getY() {
                return event.getY();
        }
    
        public float getY(int pointerIndex) {
                verifyPointerIndex(pointerIndex);
                return getY();
        }
    
        public int getPointerCount() {
                return 1;
        }
    
        public int getPointerId(int pointerIndex) {
                verifyPointerIndex(pointerIndex);
                return 0;
        }
    
        private void verifyPointerIndex(int pointerIndex) {
                if (pointerIndex > 0) {
                    throw new IllegalArgumentException(
                        "Invalid pointer index for Donut/Cupcake");
                }
        }
    
    }
    

    EclairMotionEvent.java

    import android.view.MotionEvent;
    
    public class EclairMotionEvent extends WrapMotionEvent {
    
        protected EclairMotionEvent(MotionEvent event) {
                super(event);
        }
    
        public float getX(int pointerIndex) {
                return event.getX(pointerIndex);
        }
    
        public float getY(int pointerIndex) {
                return event.getY(pointerIndex);
        }
    
        public int getPointerCount() {
                return event.getPointerCount();
        }
    
        public int getPointerId(int pointerIndex) {
                return event.getPointerId(pointerIndex);
        }
    }
    
  • 1

    我使用WebView并通过内存加载图像

    webview.loadUrl("file://...")
    

    WebView处理所有平移缩放和滚动 . 如果使用wrap_content,则webview不会大于图像,也不会显示白色区域 . WebView是更好的ImageView;)

  • 59

    在回答Janusz的原始问题时,有几种方法可以实现这一点,所有这些方法的难易程度各不相同,并在下面说明 . 使用Web视图很好,但在外观和可控性方面非常有限 . 如果您从画布中绘制位图,那么最常用的解决方案似乎是MikeOrtiz 's, Robert Foss'和/或Jacob Nordfalk建议的内容 . 有一个很好的例子可以通过PaulBourke整合android-multitouch-controller,非常适合拥有多点触控支持和自定义视图的所有类型 .

    就个人而言,如果您只是将画布绘制到位图然后将其显示在内部和ImageView中并希望能够使用多点触控放大和移动,我发现MikeOrtiz的解决方案是最简单的 . 但是,出于我的目的,他提供的Git中的代码似乎只在他的TouchImageView自定义ImageView类是唯一的子项或提供布局参数时才起作用:

    android:layout_height="match_parent"
    android:layout_height="match_parent"
    

    不幸的是由于我的布局设计,"layout_height"需要"wrap_content" . 当我将其更改为此时,图像在底部被裁剪,我无法滚动或缩放到裁剪区域 . 所以我看了一下ImageView的Source,看看Android是如何实现"onMeasure"并改变了MikeOrtiz的 .

    @Override
    protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
      //**** ADDED THIS ********/////
          int  w = (int) bmWidth;
          int  h = (int) bmHeight;
         width = resolveSize(w, widthMeasureSpec);  
         height = resolveSize(h, heightMeasureSpec);
      //**** END ********///   
    
       // width = MeasureSpec.getSize(widthMeasureSpec);   // REMOVED
       // height = MeasureSpec.getSize(heightMeasureSpec); // REMOVED
    
        //Fit to screen.
        float scale;
        float scaleX =  (float)width / (float)bmWidth;
        float scaleY = (float)height / (float)bmHeight;
    
        scale = Math.min(scaleX, scaleY);
        matrix.setScale(scale, scale);
        setImageMatrix(matrix);
        saveScale = 1f;
    
        // Center the image
        redundantYSpace = (float)height - (scale * (float)bmHeight) ;
        redundantXSpace = (float)width - (scale * (float)bmWidth);
        redundantYSpace /= (float)2;
        redundantXSpace /= (float)2;
    
        matrix.postTranslate(redundantXSpace, redundantYSpace);
    
        origWidth = width - 2 * redundantXSpace;
        origHeight = height - 2 * redundantYSpace;
       // origHeight = bmHeight;
        right = width * saveScale - width - (2 * redundantXSpace * saveScale);
        bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
    
        setImageMatrix(matrix);
    }
    

    这里resolveSize(int,int)是一个“实用程序,用于协调所需大小与MeasureSpec强加的约束,其中:

    Parameters:

    - size How big the view wants to be
     - MeasureSpec Constraints imposed by the parent
    

    Returns:

    - The size this view should be."
    

    因此,在加载图像时,本质上提供的行为与原始ImageView类更相似 . 可以进行一些更改以支持更多种改变宽高比的屏幕 . 但是现在我希望这会有所帮助 . 感谢MikeOrtiz的原始代码,非常棒的工作 .

  • 3

    你也可以试试http://code.google.com/p/android-multitouch-controller/

    图书馆真的很棒,虽然最初有点难以掌握 .

  • 6

    我刚刚整合了Robert Foss的TouchImageView:开箱即用!谢谢!

    我刚刚修改了一些代码,所以我可以从layout.xml中实例化它 .

    只需添加两个构造函数

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

    并将旧构造函数转换为init方法:

    private void init(Context context){
        //...old code ofconstructor of Robert Moss's code
    }
    
  • 2

    @Robert Foss,@ Mike Ortiz,非常感谢你的工作 . 我合并了你的工作,并完成了罗伯特课程的android> 2.0和Mike的额外工作 .

    由于我的工作,我提出了基于ViewPager的Android Touch Gallery并使用了修改后的TouchImageView . 通过URL加载图像,您可以缩放和拖动它们 . 你可以在这里找到https://github.com/Dreddik/AndroidTouchGallery

  • 2

    尝试使用 ZoomView 来缩放任何其他视图 .

    http://code.google.com/p/android-zoom-view/使用简单,免费且有趣!

  • 6

    添加到@ Mike的答案 . 我还需要双击才能在首次观看时将图像恢复为原始尺寸 . 所以我添加了一大堆“orig ...”实例变量并添加了SimpleOnGestureListener,它完成了这一操作 .

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Matrix;
    import android.graphics.PointF;
    import android.view.GestureDetector;
    import android.view.MotionEvent;
    import android.view.ScaleGestureDetector;
    import android.view.View;
    import android.widget.ImageView;
    
    public class TouchImageView extends ImageView {
    
        Matrix matrix = new Matrix();
    
        // We can be in one of these 3 states
        static final int NONE = 0;
        static final int DRAG = 1;
        static final int ZOOM = 2;
        int mode = NONE;
    
        // Remember some things for zooming
        PointF last = new PointF();
        PointF start = new PointF();
        float minScale = 1f;
        float maxScale = 3f;
        float[] m;
    
        float redundantXSpace, redundantYSpace, origRedundantXSpace, origRedundantYSpace;;
    
        float width, height;
        static final int CLICK = 3;
        static final float SAVE_SCALE = 1f;
        float saveScale = SAVE_SCALE;
    
        float right, bottom, origWidth, origHeight, bmWidth, bmHeight, origScale, origBottom,origRight;
    
        ScaleGestureDetector mScaleDetector;
        GestureDetector mGestureDetector;
    
        Context context;
    
        public TouchImageView(Context context) {
            super(context);
            super.setClickable(true);
            this.context = context;
            mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    
            matrix.setTranslate(1f, 1f);
            m = new float[9];
            setImageMatrix(matrix);
            setScaleType(ScaleType.MATRIX);
    
            setOnTouchListener(new OnTouchListener() {
    
                @Override
                public boolean onTouch(View v, MotionEvent event) {
    
                    boolean onDoubleTapEvent = mGestureDetector.onTouchEvent(event);
                    if (onDoubleTapEvent) {
                        // Reset Image to original scale values
                        mode = NONE;
                        bottom = origBottom;
                        right = origRight;
                        last = new PointF();
                        start = new PointF();
                        m = new float[9];
                        saveScale = SAVE_SCALE;
                        matrix = new Matrix();
                        matrix.setScale(origScale, origScale);
                        matrix.postTranslate(origRedundantXSpace, origRedundantYSpace);
                        setImageMatrix(matrix);
                        invalidate();
                        return true;
                    } 
    
    
                    mScaleDetector.onTouchEvent(event);
    
                    matrix.getValues(m);
                    float x = m[Matrix.MTRANS_X];
                    float y = m[Matrix.MTRANS_Y];
                    PointF curr = new PointF(event.getX(), event.getY());
    
                    switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        last.set(event.getX(), event.getY());
                        start.set(last);
                        mode = DRAG;
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (mode == DRAG) {
                            float deltaX = curr.x - last.x;
                            float deltaY = curr.y - last.y;
                            float scaleWidth = Math.round(origWidth * saveScale);
                            float scaleHeight = Math.round(origHeight * saveScale);
                            if (scaleWidth < width) {
                                deltaX = 0;
                                if (y + deltaY > 0)
                                    deltaY = -y;
                                else if (y + deltaY < -bottom)
                                    deltaY = -(y + bottom);
                            } else if (scaleHeight < height) {
                                deltaY = 0;
                                if (x + deltaX > 0)
                                    deltaX = -x;
                                else if (x + deltaX < -right)
                                    deltaX = -(x + right);
                            } else {
                                if (x + deltaX > 0)
                                    deltaX = -x;
                                else if (x + deltaX < -right)
                                    deltaX = -(x + right);
    
                                if (y + deltaY > 0)
                                    deltaY = -y;
                                else if (y + deltaY < -bottom)
                                    deltaY = -(y + bottom);
                            }
                            matrix.postTranslate(deltaX, deltaY);
                            last.set(curr.x, curr.y);
                        }
                        break;
    
                    case MotionEvent.ACTION_UP:
                        mode = NONE;
                        int xDiff = (int) Math.abs(curr.x - start.x);
                        int yDiff = (int) Math.abs(curr.y - start.y);
                        if (xDiff < CLICK && yDiff < CLICK)
                            performClick();
                        break;
    
                    case MotionEvent.ACTION_POINTER_UP:
                        mode = NONE;
                        break;
                    }
    
                    setImageMatrix(matrix);
                    invalidate();
    
                    return true; // indicate event was handled
                }
    
            });
    
            mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
                @Override
                public boolean onDoubleTapEvent(MotionEvent e) {
                    return true;
                }
            });
        }
    
        @Override
        public void setImageBitmap(Bitmap bm) {
            super.setImageBitmap(bm);
            bmWidth = bm.getWidth();
            bmHeight = bm.getHeight();
        }
    
        public void setMaxZoom(float x) {
            maxScale = x;
        }
    
        private class ScaleListener extends
                ScaleGestureDetector.SimpleOnScaleGestureListener {
            @Override
            public boolean onScaleBegin(ScaleGestureDetector detector) {
                mode = ZOOM;
                return true;
            }
    
            @Override
            public boolean onScale(ScaleGestureDetector detector) {
                float mScaleFactor = (float) Math.min(
                        Math.max(.95f, detector.getScaleFactor()), 1.05);
                float origScale = saveScale;
                saveScale *= mScaleFactor;
                if (saveScale > maxScale) {
                    saveScale = maxScale;
                    mScaleFactor = maxScale / origScale;
                } else if (saveScale < minScale) {
                    saveScale = minScale;
                    mScaleFactor = minScale / origScale;
                }
                right = width * saveScale - width
                        - (2 * redundantXSpace * saveScale);
                bottom = height * saveScale - height
                        - (2 * redundantYSpace * saveScale);
                if (origWidth * saveScale <= width
                        || origHeight * saveScale <= height) {
                    matrix.postScale(mScaleFactor, mScaleFactor, width / 2,
                            height / 2);
                    if (mScaleFactor < 1) {
                        matrix.getValues(m);
                        float x = m[Matrix.MTRANS_X];
                        float y = m[Matrix.MTRANS_Y];
                        if (mScaleFactor < 1) {
                            if (Math.round(origWidth * saveScale) < width) {
                                if (y < -bottom)
                                    matrix.postTranslate(0, -(y + bottom));
                                else if (y > 0)
                                    matrix.postTranslate(0, -y);
                            } else {
                                if (x < -right)
                                    matrix.postTranslate(-(x + right), 0);
                                else if (x > 0)
                                    matrix.postTranslate(-x, 0);
                            }
                        }
                    }
                } else {
                    matrix.postScale(mScaleFactor, mScaleFactor,
                            detector.getFocusX(), detector.getFocusY());
                    matrix.getValues(m);
                    float x = m[Matrix.MTRANS_X];
                    float y = m[Matrix.MTRANS_Y];
                    if (mScaleFactor < 1) {
                        if (x < -right)
                            matrix.postTranslate(-(x + right), 0);
                        else if (x > 0)
                            matrix.postTranslate(-x, 0);
                        if (y < -bottom)
                            matrix.postTranslate(0, -(y + bottom));
                        else if (y > 0)
                            matrix.postTranslate(0, -y);
                    }
                }
                return true;
    
            }
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            width = MeasureSpec.getSize(widthMeasureSpec);
            height = MeasureSpec.getSize(heightMeasureSpec);
            // Fit to screen.
            float scale;
            float scaleX = (float) width / (float) bmWidth;
            float scaleY = (float) height / (float) bmHeight;
            scale = Math.min(scaleX, scaleY);
            matrix.setScale(scale, scale);
            setImageMatrix(matrix);
            saveScale = SAVE_SCALE;
            origScale = scale;
    
            // Center the image
            redundantYSpace = (float) height - (scale * (float) bmHeight);
            redundantXSpace = (float) width - (scale * (float) bmWidth);
            redundantYSpace /= (float) 2;
            redundantXSpace /= (float) 2;
    
            origRedundantXSpace = redundantXSpace;
            origRedundantYSpace = redundantYSpace;
    
            matrix.postTranslate(redundantXSpace, redundantYSpace);
    
            origWidth = width - 2 * redundantXSpace;
            origHeight = height - 2 * redundantYSpace;
            right = width * saveScale - width - (2 * redundantXSpace * saveScale);
            bottom = height * saveScale - height
                    - (2 * redundantYSpace * saveScale);
            origRight = right;
            origBottom = bottom;
            setImageMatrix(matrix);
        }
    
    }
    
  • 7

    这是这个帖子的一个非常晚的补充,但我在其他地方找到了 . 这开始是一种显示非常大的图像而不会导致 OutOfMemoryError s的方法,通过在缩小时对图像进行二次采样并在放大时加载更高分辨率的图块 . 它现在支持在 ViewPager 中使用,手动旋转或使用EXIF信息(90°停止) ),覆盖选定的触摸使用 OnClickListener 或您自己的 GestureDetectorOnTouchListener 的子事件,子类化以添加叠加,平移时缩放以及动量 .

    它不是 ImageView 的一般用途替代品,因此不支持显示来自资源,仅资源和外部文件的图像 . 它需要SDK 10 .

    源代码在GitHub上,并且有一个示例说明 ViewPager 中的使用 .

    https://github.com/davemorrissey/subsampling-scale-image-view

  • 2

    您可以尝试使用LayoutParams

    public void zoom(boolean flag){
        if(flag){
            int width=40;
            int height=40;
        }
        else{
            int width=20;
            int height=20;
        }
        RelativeLayout.LayoutParams param=new RelativeLayout.LayoutParams(width,height); //use the parent layout of the ImageView;
        imageView.setLayoutParams(param); //imageView is the view which needs zooming.
    }
    

    ZoomIn = zoom(true); ZoomOut = zoom(false);

  • 0
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageDetail = (ImageView) findViewById(R.id.imageView1);
        imageDetail.setOnTouchListener(new View.OnTouchListener() {
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                ImageView view = (ImageView) v;
                System.out.println("matrix=" + savedMatrix.toString());
                switch (event.getAction() & MotionEvent.ACTION_MASK) {
                    case MotionEvent.ACTION_DOWN:
                        savedMatrix.set(matrix);
                        startPoint.set(event.getX(), event.getY());
                        mode = DRAG;
                        break;
                    case MotionEvent.ACTION_POINTER_DOWN:
                        oldDist = spacing(event);
                        if (oldDist > 10f) {
                            savedMatrix.set(matrix);
                            midPoint(midPoint, event);
                            mode = ZOOM;
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_POINTER_UP:
                        mode = NONE;
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (mode == DRAG) {
                            matrix.set(savedMatrix);
                            matrix.postTranslate(event.getX() - startPoint.x, event.getY() - startPoint.y);
                        } else if (mode == ZOOM) {
                            float newDist = spacing(event);
                            if (newDist > 10f) {
                                matrix.set(savedMatrix);
                                float scale = newDist / oldDist;
                                matrix.postScale(scale, scale, midPoint.x, midPoint.y);
                            }
                        }
                        break;
                }
                view.setImageMatrix(matrix);
                return true;
    
            }
    
            @SuppressLint("FloatMath")
            private float spacing(MotionEvent event) {
                float x = event.getX(0) - event.getX(1);
                float y = event.getY(0) - event.getY(1);
                return FloatMath.sqrt(x * x + y * y);
            }
    
            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);
            }
        });
    }
    

    和drawable文件夹应该有bticn图像文件 . 完美的工作:)

  • 0

    像下面这样的东西会做到这一点 .

    @Override public boolean onTouch(View v,MotionEvent e)
    {
    
        tap=tap2=drag=pinch=none;
        int mask=e.getActionMasked();
        posx=e.getX();posy=e.getY();
    
        float midx= img.getWidth()/2f;
        float midy=img.getHeight()/2f;
        int fingers=e.getPointerCount();
    
        switch(mask)
        {
            case MotionEvent.ACTION_POINTER_UP:
                tap2=1;break;
    
            case MotionEvent.ACTION_UP:
                tap=1;break;
    
            case MotionEvent.ACTION_MOVE:
                drag=1;
        }
        if(fingers==2){nowsp=Math.abs(e.getX(0)-e.getX(1));}
        if((fingers==2)&&(drag==0)){ tap2=1;tap=0;drag=0;}
        if((fingers==2)&&(drag==1)){ tap2=0;tap=0;drag=0;pinch=1;}
    
        if(pinch==1)
    
        {
            if(nowsp>oldsp)scale+=0.1;
            if(nowsp<oldsp)scale-=0.1;
            tap2=tap=drag=0;    
        }
        if(tap2==1)
            {
                scale-=0.1;
                tap=0;drag=0;
            }
        if(tap==1)
            {
                tap2=0;drag=0;
                scale+=0.1;
            }
        if(drag==1)
            {
                movx=posx-oldx;
                movy=posy-oldy;
                x+=movx;
                y+=movy;
                tap=0;tap2=0;
            }
        m.setTranslate(x,y);
        m.postScale(scale,scale,midx,midy);
        img.setImageMatrix(m);img.invalidate();
        tap=tap2=drag=none;
        oldx=posx;oldy=posy;
        oldsp=nowsp;
        return true;
    }
    
    
    public void onCreate(Bundle b)
    {
            super.onCreate(b);
    
        img=new ImageView(this);
        img.setScaleType(ImageView.ScaleType.MATRIX);
        img.setOnTouchListener(this);
    
        path=Environment.getExternalStorageDirectory().getPath();   
        path=path+"/DCIM"+"/behala.jpg";
        byte[] bytes;
        bytes=null;
        try{
            FileInputStream fis;
            fis=new FileInputStream(path);
            BufferedInputStream bis;
            bis=new BufferedInputStream(fis);
            bytes=new byte[bis.available()];
            bis.read(bytes);
            if(bis!=null)bis.close();
            if(fis!=null)fis.close();
    
         }
        catch(Exception e)
            {
            ret="Nothing";
            }
        Bitmap bmp=BitmapFactory.decodeByteArray(bytes,0,bytes.length);
    
        img.setImageBitmap(bmp);
    
        setContentView(img);
    }
    

    查看完整程序,请参见此处:Program to zoom image in android

相关问题