Как я могу получить функцию масштабирования изображений?

StackOverflow https://stackoverflow.com/questions/2537238

  •  22-09-2019
  •  | 
  •  

Вопрос

Существует ли распространенный способ показать большое изображение и позволить пользователю увеличивать и уменьшать масштаб и панорамировать изображение?

До сих пор я находил два способа:

  1. перезапись ImageView - это кажется немного перебором для такой распространенной проблемы.
  2. используя webview, но с меньшим контролем над общим макетом и т.д.
Это было полезно?

Решение 3

Я использовал WebView и загрузил изображение из памяти через

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

WebView обрабатывает все операции панорамирования, масштабирования и прокрутки.Если вы используете wrap_content, webview не будет больше изображения, и белые области не будут показаны.WebView - лучший ImageView ;)

Другие советы

Обновить

Я только что предоставил TouchImageView новое обновление.Теперь он включает в себя масштабирование двойным касанием и бросок в дополнение к панорамированию и пинч-зуму.Приведенный ниже код является очень встречался.Вы можете ознакомиться с проект на github чтобы получить последний код.

ИСПОЛЬЗОВАНИЕ

Разместите TouchImageView.java в своем проекте.Затем его можно использовать так же, как ImageView.Пример:

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

Если вы используете TouchImageView в xml, то вы должны предоставить полный пакет name, потому что это пользовательский вид.Пример:

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

Примечание:Я удалил свой предыдущий ответ, который включал в себя какой-то очень старый код, и теперь ссылаюсь прямо на самый обновленный код на github.

Просмотрщик

Если вы заинтересованы в том, чтобы поместить TouchImageView в ViewPager, обратитесь к этому ответу.

Я адаптировал некоторый код для создания TouchImageView, который поддерживает мультитач (> 2.1).Это вдохновлено книгой Привет, Андроид!(3-е издание)

Он содержится в следующих 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);
    }
}

В ответ на первоначальный вопрос Януша, есть несколько способов достичь этого, все из которых различаются по уровню сложности и были изложены ниже.Использование веб-представления - это хорошо, но оно очень ограничено с точки зрения внешнего вида и управляемости.Если вы рисуете растровое изображение на холсте, наиболее универсальными решениями, которые были предложены, по-видимому, являются решения Майкортиса, Роберта Фосса и / или Джейкоба Нордфолка.Существует отличный пример включения Android-мультитач-контроллера с помощью Полбурк, и отлично подходит для поддержки мультитач и всех типов пользовательских представлений.

Лично я считаю, что если вы просто рисуете холст на растровом изображении, а затем отображаете его внутри и в режиме ImageView и хотите иметь возможность увеличивать масштаб и перемещаться с помощью мультитач, решение MikeOrtiz от MikeOrtiz является самым простым.Однако для моих целей код из Мерзавец то, что он предоставил, похоже, работает только тогда, когда его пользовательский класс TouchImageView ImageView является единственным дочерним или предоставляет параметры макета как:

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

К сожалению, из-за моего дизайна макета мне понадобился "wrap_content" для "layout_height".Когда я изменил его на это, изображение было обрезано внизу, и я не мог прокрутить или приблизить к обрезанной области.Итак, я взглянул на Источник для ImageView просто посмотреть, как 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, где :

Параметры:

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

ВОЗВРАТ:

 - The size this view should be."

Таким образом, по сути, обеспечивая поведение, немного более похожее на исходный класс ImageView, при загрузке изображения.Можно было бы внести еще некоторые изменения для поддержки большего разнообразия экранов, которые изменяют соотношение сторон.Но сейчас я надеюсь, что это поможет.Спасибо MikeOrtiz за его оригинальный код, отличная работа.

Вы также могли бы попробовать http://code.google.com/p/android-multitouch-controller/

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

Я только что интегрировал 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
}

@Роберт Фосс, @Майк Ортис, большое вам спасибо за вашу работу.Я объединил вашу работу и выполнил Robert classes для Android > 2.0 с дополнительной работой Майка.

В результате моей работы я представляю Android Touch Gallery, основанную на ViewPager и использующую модифицированный TouchImageView.Изображения загружаются по URL, и вы можете масштабировать и перетаскивать их.Вы можете найти его здесь https://github.com/Dreddik/AndroidTouchGallery

Попробуйте использовать ZoomView для масштабирования любого другого вида.

http://code.google.com/p/android-zoom-view/ это легко, бесплатно и весело в использовании!

Добавление к ответу @Mike.Мне также потребовалось двойное нажатие, чтобы восстановить исходные размеры изображения при первом просмотре.Итак, я добавил целую кучу переменных экземпляра "origin ..." и добавил 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);
    }

}

Это очень позднее дополнение к этой теме, но я работал над представлением изображений, которое поддерживает масштабирование и панорамирование и имеет пару функций, которых я больше нигде не нашел.Это начиналось как способ отображения очень больших изображений, не вызывая OutOfMemoryErrors, путем субдискретизации изображения при уменьшении масштаба и загрузки фрагментов с более высоким разрешением при увеличении.Теперь он поддерживает использование в ViewPager, поворот вручную или с использованием информации EXIF (остановки на 90 °), переопределение выбранных событий касания с помощью OnClickListener или ваш собственный GestureDetector или OnTouchListener, создание подклассов для добавления наложений, панорамирования при масштабировании и создания импульса.

Он не предназначен в качестве замены общего назначения для ImageView so не расширяет его и не поддерживает отображение изображений из ресурсов, только ресурсы и внешние файлы.Для этого требуется SDK 10.

Исходный код находится на GitHub, и там есть пример, иллюстрирующий использование в ViewPager.

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

Вы можете попробовать использовать 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 = масштабирование (true);Уменьшение масштаба = увеличение (false);

@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.отлично работает :)

Это сделает что-то вроде приведенного ниже.

@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);
}

Для просмотра полной программы смотрите здесь: Программа для масштабирования изображения в Android

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top