package com.yazuo.zoomimagedemo;
import java.util.Observable;
import java.util.Observer;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
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);
setZoomState(mZoomControl.getZoomState());
setOnTouchListener(mZoomListener);
mZoomControl.setAspectQuotient(getAspectQuotient());
}
public void zoomImage(float f, float x, float y)
{
mZoomControl.zoom(f, x, y);
}
public void setImage(Bitmap bitmap) {
mBitmap = bitmap;
mAspectQuotient.updateAspectQuotient(getWidth(), getHeight(), mBitmap.getWidth(), mBitmap
.getHeight());
mAspectQuotient.notifyObservers();
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 = mAspectQuotient.get();
final int viewWidth = getWidth();
final int viewHeight = getHeight();
final int bitmapWidth = mBitmap.getWidth();
final int bitmapHeight = mBitmap.getHeight();
Log.d("ZoomImageView", "viewWidth = " + viewWidth);
Log.d("ZoomImageView", "viewHeight = " + viewHeight);
Log.d("ZoomImageView", "bitmapWidth = " + bitmapWidth);
Log.d("ZoomImageView", "bitmapHeight = " + bitmapHeight);
final float panX = mState.getPanX();
final float panY = mState.getPanY();
final float zoomX = mState.getZoomX(aspectQuotient) * viewWidth / bitmapWidth;
final float zoomY = mState.getZoomY(aspectQuotient) * viewHeight / bitmapHeight;
// Setup source and destination rectangles
mRectSrc.left = (int)(panX * bitmapWidth - viewWidth / (zoomX * 2));
mRectSrc.top = (int)(panY * bitmapHeight - viewHeight / (zoomY * 2));
mRectSrc.right = (int)(mRectSrc.left + viewWidth / zoomX);
mRectSrc.bottom = (int)(mRectSrc.top + viewHeight / zoomY);
// mRectDst.left = getLeft();
mRectDst.left = 0;
mRectDst.top = 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 (mRectSrc.top < 0) {
mRectDst.top += -mRectSrc.top * zoomY;
mRectSrc.top = 0;
}
if (mRectSrc.bottom > bitmapHeight) {
mRectDst.bottom -= (mRectSrc.bottom - bitmapHeight) * zoomY;
mRectSrc.bottom = bitmapHeight;
}
// int width = mRectDst.right - mRectDst.left;
// int heigth = mRectDst.bottom - mRectDst.top;
mRectDst.left = 0;
mRectDst.top = 0;
// mRectDst.right = width;
// mRectDst.bottom = heigth;
mRectDst.right = viewWidth;
mRectDst.bottom = viewHeight;
Log.d("ZoomImageView", "mRectSrc.top" + mRectSrc.top);
Log.d("ZoomImageView", "mRectSrc.bottom" + mRectSrc.bottom);
Log.d("ZoomImageView", "mRectSrc.left" + mRectSrc.left);
Log.d("ZoomImageView", "mRectSrc.right" + mRectSrc.right);
Log.d("ZoomImageView", "mRectDst.top" + mRectDst.top);
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) {
super.onLayout(changed, left, top, right, bottom);
mAspectQuotient.updateAspectQuotient(right - left, bottom - top, mBitmap.getWidth(),
mBitmap.getHeight());
mAspectQuotient.notifyObservers();
}
@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 (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mOldCounts = 1;
mFirstX = event.getX();
mFirstY = event.getY();
break;
case MotionEvent.ACTION_MOVE: {
float fFirstX = event.getX();
float fFirstY = event.getY();
int nCounts = event.getPointerCount();
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 = event.getX(event.getPointerId(nCounts - 1));
mSecondY = event.getY(event.getPointerId(nCounts - 1));
mOldCounts = nCounts;
}
else
{
float fSecondX = event.getX(event.getPointerId(nCounts - 1));
float fSecondY = event.getY(event.getPointerId(nCounts - 1));
double nLengthOld = getLength(mFirstX, mFirstY, mSecondX, mSecondY);
double nLengthNow = getLength(fF
- 1
- 2
- 3
- 4
- 5
- 6
前往页