图片的放大与缩小

阅读: 评论:0

图片的放大与缩小

图片的放大与缩小

一、自定义imageview的实现,实现了放大与缩小.

public class ZoomImageView extends View implements Observer {/** Paint object used when drawing bitmap. */
    private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
    /** Rectangle used (and re-used) for cropping source image. */
    private final Rect mRectSrc = new Rect();
    /** Rectangle used (and re-used) for specifying drawing area on canvas. */
    private final Rect mRectDst = new Rect();
    /** Object holding aspect quotient */
    private final AspectQuotient mAspectQuotient = new AspectQuotient();
    /** The bitmap that we're zooming in, and drawing on the screen. */
    private Bitmap mBitmap;
    /** State of the zoom. */
    private ZoomState mState;
    private BasicZoomControl mZoomControl;
    private BasicZoomListener mZoomListener;

    public ZoomImageView(Context context, AttributeSet attrs) {super(context, attrs);
        mZoomControl = new BasicZoomControl();
        mZoomListener = new BasicZoomListener();
        mZoomListener.setZoomControl(mZoomControl);
        ZoomState());
        setOnTouchListener(mZoomListener);
        mZoomControl.setAspectQuotient(getAspectQuotient());
    }public void zoomImage(float f, float x, float y) {(f, x, y);
    }public void setImage(Bitmap bitmap) {mBitmap = bitmap;
        try {mAspectQuotient.updateAspectQuotient(getWidth(), getHeight(),
                    Width(), Height());
        }catch (Exception e){e.printStackTrace();
        }ifyObservers();
        invalidate();
    }private void setZoomState(ZoomState state) {if (mState != null) {mState.deleteObserver(this);
        }mState = state;
        mState.addObserver(this);
        invalidate();
    }private AspectQuotient getAspectQuotient() {return mAspectQuotient;
    }@Override
    protected void onDraw(Canvas canvas) {if (mBitmap != null && mState != null) {Log.d("ZoomImageView", "OnDraw");
            final float aspectQuotient = ();
            final int viewWidth = getWidth();
            final int viewHeight = getHeight();
            final int bitmapWidth = Width();
            final int bitmapHeight = Height();
            Log.d("ZoomImageView", "viewWidth = " + viewWidth);
            Log.d("ZoomImageView", "viewHeight = " + viewHeight);
            Log.d("ZoomImageView", "bitmapWidth = " + bitmapWidth);
            Log.d("ZoomImageView", "bitmapHeight = " + bitmapHeight);
            final float panX = PanX();
            final float panY = PanY();
            final float zoomX = ZoomX(aspectQuotient) * viewWidth/ bitmapWidth;
            final float zoomY = ZoomY(aspectQuotient) * viewHeight/ bitmapHeight;
            // Setup source and destination rectangles
            mRectSrc.left = (int) (panX * bitmapWidth - viewWidth / (zoomX * 2));
            p = (int) (panY * bitmapHeight - viewHeight/ (zoomY * 2));
            mRectSrc.right = (int) (mRectSrc.left + viewWidth / zoomX);
            mRectSrc.bottom = (int) (p + viewHeight / zoomY);
            // mRectDst.left = getLeft();
            mRectDst.left = 0;
            p = 0;
            // mRectDst.right = getRight();
            mRectDst.right = getWidth();
            mRectDst.bottom = getHeight();
            // Adjust source rectangle so that it fits within the source image.
            if (mRectSrc.left < 0) {mRectDst.left += -mRectSrc.left * zoomX;
                mRectSrc.left = 0;
            }if (mRectSrc.right > bitmapWidth) {mRectDst.right -= (mRectSrc.right - bitmapWidth) * zoomX;
                mRectSrc.right = bitmapWidth;
            }if (p < 0) {p += -p * zoomY;
                p = 0;
            }if (mRectSrc.bottom > bitmapHeight) {mRectDst.bottom -= (mRectSrc.bottom - bitmapHeight) * zoomY;
                mRectSrc.bottom = bitmapHeight;
            }mRectDst.left = 0;
            p = 0;
            mRectDst.right = viewWidth;
            mRectDst.bottom = viewHeight;
            Log.d("ZoomImageView", &#p" + p);
            Log.d("ZoomImageView", "mRectSrc.bottom" + mRectSrc.bottom);
            Log.d("ZoomImageView", "mRectSrc.left" + mRectSrc.left);
            Log.d("ZoomImageView", "mRectSrc.right" + mRectSrc.right);
            Log.d("ZoomImageView", &#p" + p);
            Log.d("ZoomImageView", "mRectDst.bottom" + mRectDst.bottom);
            Log.d("ZoomImageView", "mRectDst.left" + mRectDst.left);
            Log.d("ZoomImageView", "mRectDst.right" + mRectDst.right);
            canvas.drawBitmap(mBitmap, mRectSrc, mRectDst, mPaint);
        }}@Override
    protected void onLayout(boolean changed, int left, int top, int right,
                            int bottom) {Layout(changed, left, top, right, bottom);
        try {mAspectQuotient.updateAspectQuotient(right - left, bottom - top,
            Width(), Height());
        }catch (Exception e){e.printStackTrace();
        }ifyObservers();
    }@Override
    public void update(Observable observable, Object data) {invalidate();
    }private class BasicZoomListener implements View.OnTouchListener {/** Zoom control to manipulate */
        private BasicZoomControl mZoomControl;
        private float mFirstX = -1;
        private float mFirstY = -1;
        private float mSecondX = -1;
        private float mSecondY = -1;
        private int mOldCounts = 0;
        /**
         * Sets the zoom control to manipulate
         *
         * @param control
         *            Zoom control
         */
        public void setZoomControl(BasicZoomControl control) {mZoomControl = control;
        }public boolean onTouch(View v, MotionEvent event) {switch (Action()) {case MotionEvent.ACTION_DOWN:mOldCounts = 1;
                    mFirstX = X();
                    mFirstY = Y();
                    break;
                case MotionEvent.ACTION_MOVE: {float fFirstX = X();
                    float fFirstY = Y();
                    int nCounts = PointerCount();
                    if (1 == nCounts) {mOldCounts = 1;
                        float dx = (fFirstX - mFirstX) / v.getWidth();
                        float dy = (fFirstY - mFirstY) / v.getHeight();
                        mZoomControl.pan(-dx, -dy);
                    } else if (1 == mOldCounts) {mSecondX = PointerId(nCounts - 1));
                        mSecondY = PointerId(nCounts - 1));
                        mOldCounts = nCounts;
                    } else {float fSecondX = PointerId(nCounts - 1));
                        float fSecondY = PointerId(nCounts - 1));
                        double nLengthOld = getLength(mFirstX, mFirstY, mSecondX,
                                mSecondY);
                        double nLengthNow = getLength(fFirstX, fFirstY, fSecondX,
                                fSecondY);
                        float d = (float) ((nLengthNow - nLengthOld) / v.getWidth());
                        ((float) Math.pow(20, d),
                                ((fFirstX + fSecondX) / 2 / v.getWidth()),
                                ((fFirstY + fSecondY) / 2 / v.getHeight()));
                        mSecondX = fSecondX;
                        mSecondY = fSecondY;
                    }mFirstX = fFirstX;
                    mFirstY = fFirstY;
                    break;
                }}return true;
        }private double getLength(float x1, float y1, float x2, float y2) {return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
        }}private class BasicZoomControl implements Observer {/** Minimum zoom level limit */
        private static final float MIN_ZOOM = 1;
        /** Maximum zoom level limit */
        private static final float MAX_ZOOM = 16;
        /** Zoom state under control */
        private final ZoomState mState = new ZoomState();
        /** Object holding aspect quotient of view and content */
        private AspectQuotient mAspectQuotient;
        /**
         * Set reference object holding aspect quotient
         *
         * @param aspectQuotient
         *            Object holding aspect quotient
         */
        public void setAspectQuotient(AspectQuotient aspectQuotient) {if (mAspectQuotient != null) {mAspectQuotient.deleteObserver(this);
            }mAspectQuotient = aspectQuotient;
            mAspectQuotient.addObserver(this);
        }/**
         * Get zoom state being controlled
         *
         * @return The zoom state
         */
        public ZoomState getZoomState() {return mState;
        }/**
         * Zoom
         *
         * @param f
         *            Factor of zoom to apply
         * @param x
         *            X-coordinate of invariant position
         * @param y
         *            Y-coordinate of invariant position
         */
        public void zoom(float f, float x, float y) {// Log.d("Zoom", "zoom f = " + f);
            final float aspectQuotient = ();
            final float prevZoomX = ZoomX(aspectQuotient);
            final float prevZoomY = ZoomY(aspectQuotient);
            mState.Zoom() * f);
            limitZoom();
            final float newZoomX = ZoomX(aspectQuotient);
            final float newZoomY = ZoomY(aspectQuotient);
            // Pan to keep x and y coordinate invariant
            mState.PanX() + (x - .5f)* (1f / prevZoomX - 1f / newZoomX));
            mState.PanY() + (y - .5f)* (1f / prevZoomY - 1f / newZoomY));
            limitPan();
            ifyObservers();
        }/**
         * Pan
         *
         * @param dx
         *            Amount to pan in x-dimension
         * @param dy
         *            Amount to pan in y-dimension
         */
        public void pan(float dx, float dy) {final float aspectQuotient = ();
            mState.PanX() + dx/ ZoomX(aspectQuotient));
            mState.PanY() + dy/ ZoomY(aspectQuotient));
            limitPan();
            ifyObservers();
        }/**
         * Help function to figure out max delta of pan from center position.
         *
         * @param zoom
         *            Zoom value
         * @return Max delta of pan
         */
        private float getMaxPanDelta(float zoom) {return Math.max(0f, .5f * ((zoom - 1) / zoom));
        }/**
         * Force zoom to stay within limits
         */
        private void limitZoom() {if (Zoom() < MIN_ZOOM) {mState.setZoom(MIN_ZOOM);
            } else if (Zoom() > MAX_ZOOM) {mState.setZoom(MAX_ZOOM);
            }}/**
         * Force pan to stay within limits
         */
        private void limitPan() {final float aspectQuotient = ();
            final float zoomX = ZoomX(aspectQuotient);
            final float zoomY = ZoomY(aspectQuotient);
            final float panMinX = .5f - getMaxPanDelta(zoomX);
            final float panMaxX = .5f + getMaxPanDelta(zoomX);
            final float panMinY = .5f - getMaxPanDelta(zoomY);
            final float panMaxY = .5f + getMaxPanDelta(zoomY);
            if (PanX() < panMinX) {mState.setPanX(panMinX);
            }if (PanX() > panMaxX) {mState.setPanX(panMaxX);
            }if (PanY() < panMinY) {mState.setPanY(panMinY);
            }if (PanY() > panMaxY) {mState.setPanY(panMaxY);
            }}// Observable interface implementation

        public void update(Observable observable, Object data) {limitZoom();
            limitPan();
        }}private class AspectQuotient extends Observable {/**
         * Aspect quotient
         */
        private float mAspectQuotient;
        // Public methods
        /**
         * Gets aspect quotient
         *
         * @return The aspect quotient
         */
        public float get() {return mAspectQuotient;
        }/**
         * Updates and recalculates aspect quotient based on supplied view and
         * content dimensions.
         *
         * @param viewWidth
         *            Width of view
         * @param viewHeight
         *            Height of view
         * @param contentWidth
         *            Width of content
         * @param contentHeight
         *            Height of content
         */
        public void updateAspectQuotient(float viewWidth, float viewHeight,
                                         float contentWidth, float contentHeight) {final float aspectQuotient = (contentWidth / contentHeight)/ (viewWidth / viewHeight);
            if (aspectQuotient != mAspectQuotient) {mAspectQuotient = aspectQuotient;
                setChanged();
            }}}private class ZoomState extends Observable {/**
         * Zoom level A value of 1.0 means the content fits the view.
         */
        private float mZoom;
        /**
         * Pan position x-coordinate X-coordinate of zoom window center
         * position, relative to the width of the content.
         */
        private float mPanX;
        /**
         * Pan position y-coordinate Y-coordinate of zoom window center
         * position, relative to the height of the content.
         */
        private float mPanY;
        // Public methods
        /**
         * Get current x-pan
         *
         * @return current x-pan
         */
        public float getPanX() {return mPanX;
        }/**
         * Get current y-pan
         *
         * @return Current y-pan
         */
        public float getPanY() {return mPanY;
        }/**
         * Get current zoom value
         *
         * @return Current zoom value
         */
        public float getZoom() {return mZoom;
        }/**
         * Help function for calculating current zoom value in x-dimension
         *
         * @param aspectQuotient
         *            (Aspect ratio content) / (Aspect ratio view)
         * @return Current zoom value in x-dimension
         */
        public float getZoomX(float aspectQuotient) {return Math.min(mZoom, mZoom * aspectQuotient);
        }/**
         * Help function for calculating current zoom value in y-dimension
         *
         * @param aspectQuotient
         *            (Aspect ratio content) / (Aspect ratio view)
         * @return Current zoom value in y-dimension
         */
        public float getZoomY(float aspectQuotient) {return Math.min(mZoom, mZoom / aspectQuotient);
        }/**
         * Set pan-x
         *
         * @param panX
         *            Pan-x value to set
         */
        public void setPanX(float panX) {if (panX != mPanX) {mPanX = panX;
                setChanged();
            }}/**
         * Set pan-y
         *
         * @param panY
         *            Pan-y value to set
         */
        public void setPanY(float panY) {if (panY != mPanY) {mPanY = panY;
                setChanged();
            }}/**
         * Set zoom
         *
         * @param zoom
         *            Zoom value to set
         */
        public void setZoom(float zoom) {if (zoom != mZoom) {mZoom = zoom;
                setChanged();
            }}}
}
    要使用这个自定义view,就在配置文件中定义,显示的方法就是setImage(bitmap);
    ZoomImageView iv = new ZoomImageView(this,null);
    Bitmap bitmap = BitmapUtil.lessenUriImage(this,imageurl);
    iv.setImage(bitmap);

本文发布于:2024-02-04 11:52:55,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170706554455312.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

下一篇:vue element
标签:图片
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23