Android:缩放图像并使用当前缩放在图像上画线

Android:缩放图像并使用当前缩放在图像上画线,android,bitmap,zooming,draw,Android,Bitmap,Zooming,Draw,我正在使用ImageView支持缩放。现在我正在扩展ImageView以便可以在画布上绘制。目前,我已设置ImageResource设置为可绘制和onDraw(画布);我在一条路径上画了一些线,然后在画布上画了一些线 问题是,当我尝试缩放时,图像会完美地缩放,但在画布上绘制的图形不会缩放。它只是呆在原地 Steps - First screen Image view - Zoom Imageview. - Now Draw on Image like signature,line,circle

我正在使用ImageView支持缩放。现在我正在扩展ImageView以便可以在画布上绘制。目前,我已设置ImageResource设置为可绘制和onDraw(画布);我在一条路径上画了一些线,然后在画布上画了一些线

问题是,当我尝试缩放时,图像会完美地缩放,但在画布上绘制的图形不会缩放。它只是呆在原地

Steps
-  First screen Image view
- Zoom Imageview.
- Now Draw on Image like signature,line,circle etc
- Then when zoom out at that time it should be display when you draw object. 

// Single Tone class
public class AppController extends Application {

// sensible place to declare a log tag for the application
public static final String LOG_TAG = AppController.class.getName();

// instance
private static AppController instance = null;

public static AppController getInstance() {
    checkInstance();
    return instance;
}

private static void checkInstance() {
    if (instance == null)
        throw new IllegalStateException("Application not created yet!");
}

@Override
public void onCreate() {
    super.onCreate();
    instance = this;
}

}

//CUSTOM IMAGEVIEW
import java.io.ByteArrayOutputStream;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class ScaleImageView extends ImageView implements OnTouchListener {

static final float STROKE_WIDTH = 10f;
static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;

float lastTouchX;
float lastTouchY;
final RectF dirtyRect = new RectF();

private Context mContext;
private float MAX_SCALE = 2f;

private static Matrix mMatrix;
private final float[] mMatrixValues = new float[9];

// display width height.
private int mWidth;
private int mHeight;

private int mIntrinsicWidth;
private int mIntrinsicHeight;

private float mScale;
private float mMinScale;

private float mPrevDistance;
private boolean isScaling;

private int mPrevMoveX;
private int mPrevMoveY;
private GestureDetector mDetector;

Paint paint = new Paint();
public static Path path = new Path();

public static int imageheight, imagewidth;

String TAG = "ScaleImageView";

public ScaleImageView(Context context, AttributeSet attr) {
    super(context, attr);
    this.mContext = context;
    initialize();
}

public ScaleImageView(Context context) {
    super(context);
    this.mContext = context;
    initialize();
}

private void resetDirtyRect(float eventX, float eventY) {
    dirtyRect.left = Math.min(lastTouchX, eventX);
    dirtyRect.right = Math.max(lastTouchX, eventX);
    dirtyRect.top = Math.min(lastTouchY, eventY);
    dirtyRect.bottom = Math.max(lastTouchY, eventY);
}

@Override
public void setImageBitmap(Bitmap bm) {
    super.setImageBitmap(bm);
    this.initialize();
}

@Override
public void setImageResource(int resId) {
    super.setImageResource(resId);
    this.initialize();
}

private void initialize() {
    this.setScaleType(ScaleType.MATRIX);
    this.mMatrix = new Matrix();
    Drawable d = getDrawable();

    paint.setAntiAlias(true);
    paint.setColor(Color.RED);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeWidth(STROKE_WIDTH);

    if (d != null) {
        mIntrinsicWidth = d.getIntrinsicWidth();
        mIntrinsicHeight = d.getIntrinsicHeight();
        setOnTouchListener(this);
    }
    mDetector = new GestureDetector(mContext,
            new GestureDetector.SimpleOnGestureListener() {
                @Override
                public boolean onDoubleTap(MotionEvent e) {
                    maxZoomTo((int) e.getX(), (int) e.getY());
                    cutting();
                    return super.onDoubleTap(e);
                }
            });

}

@Override
protected boolean setFrame(int l, int t, int r, int b) {
    mWidth = r - l;
    mHeight = b - t;

    mMatrix.reset();
    int r_norm = r - l;
    mScale = (float) r_norm / (float) mIntrinsicWidth;

    int paddingHeight = 0;
    int paddingWidth = 0;
    // scaling vertical
    if (mScale * mIntrinsicHeight > mHeight) {
        mScale = (float) mHeight / (float) mIntrinsicHeight;
        mMatrix.postScale(mScale, mScale);
        paddingWidth = (r - mWidth) / 2;
        paddingHeight = 0;
        // scaling horizontal
    } else {
        mMatrix.postScale(mScale, mScale);
        paddingHeight = (b - mHeight) / 2;
        paddingWidth = 0;
    }
    mMatrix.postTranslate(paddingWidth, paddingHeight);

    setImageMatrix(mMatrix);
    mMinScale = mScale;
    zoomTo(mScale, mWidth / 2, mHeight / 2);
    cutting();
    return super.setFrame(l, t, r, b);
}

protected float getValue(Matrix matrix, int whichValue) {
    matrix.getValues(mMatrixValues);
    return mMatrixValues[whichValue];
}

protected float getScale() {
    return getValue(mMatrix, Matrix.MSCALE_X);
}

public float getTranslateX() {
    return getValue(mMatrix, Matrix.MTRANS_X);
}

protected float getTranslateY() {
    return getValue(mMatrix, Matrix.MTRANS_Y);
}

protected void maxZoomTo(int x, int y) {
    if (mMinScale != getScale() && (getScale() - mMinScale) > 0.1f) {
        // threshold 0.1f
        float scale = mMinScale / getScale();
        zoomTo(scale, x, y);
    } else {
        float scale = MAX_SCALE / getScale();
        zoomTo(scale, x, y);
    }
}

public void zoomTo(float scale, int x, int y) {
    if (getScale() * scale < mMinScale) {
        return;
    }
    if (scale >= 1 && getScale() * scale > MAX_SCALE) {
        return;
    }
    mMatrix.postScale(scale, scale);
    // move to center
    mMatrix.postTranslate(-(mWidth * scale - mWidth) / 2,
            -(mHeight * scale - mHeight) / 2);

    // move x and y distance
    mMatrix.postTranslate(-(x - (mWidth / 2)) * scale, 0);
    mMatrix.postTranslate(0, -(y - (mHeight / 2)) * scale);
    setImageMatrix(mMatrix);
}

public void cutting() {
    int width = (int) (mIntrinsicWidth * getScale());
    int height = (int) (mIntrinsicHeight * getScale());

    imagewidth = width;
    imageheight = height;

    if (getTranslateX() < -(width - mWidth)) {
        mMatrix.postTranslate(-(getTranslateX() + width - mWidth), 0);
    }
    if (getTranslateX() > 0) {
        mMatrix.postTranslate(-getTranslateX(), 0);
    }
    if (getTranslateY() < -(height - mHeight)) {
        mMatrix.postTranslate(0, -(getTranslateY() + height - mHeight));
    }
    if (getTranslateY() > 0) {
        mMatrix.postTranslate(0, -getTranslateY());
    }
    if (width < mWidth) {
        mMatrix.postTranslate((mWidth - width) / 2, 0);
    }
    if (height < mHeight) {
        mMatrix.postTranslate(0, (mHeight - height) / 2);
    }
    setImageMatrix(mMatrix);
}

private float distance(float x0, float x1, float y0, float y1) {
    float x = x0 - x1;
    float y = y0 - y1;
    return FloatMath.sqrt(x * x + y * y);
}

private float dispDistance() {
    return FloatMath.sqrt(mWidth * mWidth + mHeight * mHeight);
}

public void clear() {
    path.reset();
    invalidate();
}

public static void save() {

    Bitmap returnedBitmap = Bitmap.createBitmap(
            ScaleImageViewActivity.imageview.getWidth(),
            ScaleImageViewActivity.imageview.getHeight(),
            Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(returnedBitmap);

    Drawable bgDrawable = ScaleImageViewActivity.imageview.getDrawable();

    if (bgDrawable != null)
        bgDrawable.draw(canvas);
    else
        canvas.drawColor(Color.WHITE);

    ScaleImageViewActivity.imageview.draw(canvas);

    ByteArrayOutputStream bs = new ByteArrayOutputStream();
    returnedBitmap.compress(Bitmap.CompressFormat.PNG, 50, bs);

    Bitmap FinalBitmap = BitmapFactory.decodeByteArray(bs.toByteArray(), 0,
            bs.toByteArray().length);

    ScaleImageViewActivity.imageview.setImageBitmap(FinalBitmap);
    path.reset();

    // ScaleImageViewActivity.imageview.setImageMatrix(mMatrix);

}

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
    if (!ScaleImageViewActivity.flag) {

        if (mDetector.onTouchEvent(event)) {
            return true;
        }
        int touchCount = event.getPointerCount();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_1_DOWN:
        case MotionEvent.ACTION_POINTER_2_DOWN:
            if (touchCount >= 2) {
                float distance = distance(event.getX(0), event.getX(1),
                        event.getY(0), event.getY(1));
                mPrevDistance = distance;
                isScaling = true;
            } else {
                mPrevMoveX = (int) event.getX();
                mPrevMoveY = (int) event.getY();
            }
        case MotionEvent.ACTION_MOVE:
            if (touchCount >= 2 && isScaling) {
                float dist = distance(event.getX(0), event.getX(1),
                        event.getY(0), event.getY(1));
                float scale = (dist - mPrevDistance) / dispDistance();
                mPrevDistance = dist;
                scale += 1;
                scale = scale * scale;
                zoomTo(scale, mWidth / 2, mHeight / 2);
                cutting();
            } else if (!isScaling) {
                int distanceX = mPrevMoveX - (int) event.getX();
                int distanceY = mPrevMoveY - (int) event.getY();
                mPrevMoveX = (int) event.getX();
                mPrevMoveY = (int) event.getY();
                mMatrix.postTranslate(-distanceX, -distanceY);
                cutting();
            }
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
        case MotionEvent.ACTION_POINTER_2_UP:
            if (event.getPointerCount() <= 1) {
                isScaling = false;
            }
            break;
        }
    } else {
        float eventX = event.getX();
        float eventY = event.getY();

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            path.moveTo(eventX, eventY);
            lastTouchX = eventX;
            lastTouchY = eventY;
            return true;

        case MotionEvent.ACTION_MOVE:

        case MotionEvent.ACTION_UP:

            resetDirtyRect(eventX, eventY);
            int historySize = event.getHistorySize();
            for (int i = 0; i < historySize; i++) {
                float historicalX = event.getHistoricalX(i);
                float historicalY = event.getHistoricalY(i);
                path.lineTo(historicalX, historicalY);
            }
            path.lineTo(eventX, eventY);
            break;
        }

        invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH),
                (int) (dirtyRect.top - HALF_STROKE_WIDTH),
                (int) (dirtyRect.right + HALF_STROKE_WIDTH),
                (int) (dirtyRect.bottom + HALF_STROKE_WIDTH));

        lastTouchX = eventX;
        lastTouchY = eventY;
    }
    return true;
}

@Override
protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);
    if (ScaleImageViewActivity.flag)
        canvas.drawPath(path, paint);
}

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
    return super.onTouchEvent(event);
}

}

//ACTIVITY

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ScaleImageViewActivity extends Activity implements OnClickListener {

Button btndraw, btnzoom, btnsave;

public static ScaleImageView imageview;
public static boolean flag = true;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    initwidget();
}

private void initwidget() {

    imageview = (ScaleImageView) findViewById(R.id.image);

    btnsave = (Button) findViewById(R.id.activity_main_save);
    btndraw = (Button) findViewById(R.id.activity_main_zoom_draw);
    btnzoom = (Button) findViewById(R.id.activity_main_zoom_zoom);

    btndraw.setOnClickListener(this);
    btnzoom.setOnClickListener(this);
    btnsave.setOnClickListener(this);
}

@Override
public void onClick(View arg0) {
    // TODO Auto-generated method stub
    if (btndraw.equals(arg0)) {
        flag = true;
    } else if (btnzoom.equals(arg0)) {
        flag = false;
    } else if (btnsave.equals(arg0)) {
        ScaleImageView.save();
    }
}
}
步骤
-第一屏幕图像视图
-缩放图像视图。
-现在画上签名、线条、圆圈等图像
-然后,当在那个时候缩小时,它应该在绘制对象时显示。
//单音类
公共类AppController扩展应用程序{
//为应用程序声明日志标记的合理位置
公共静态最终字符串LOG_TAG=AppController.class.getName();
//实例
私有静态AppController实例=null;
公共静态AppController getInstance(){
checkInstance();
返回实例;
}
私有静态void checkInstance(){
if(实例==null)
抛出新的IllegalStateException(“尚未创建应用程序!”);
}
@凌驾
public void onCreate(){
super.onCreate();
实例=此;
}
}
//自定义图像视图
导入java.io.ByteArrayOutputStream;
导入android.annotation.SuppressLint;
导入android.content.Context;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Matrix;
导入android.graphics.Paint;
导入android.graphics.Path;
导入android.graphics.RectF;
导入android.graphics.drawable.drawable;
导入android.util.AttributeSet;
导入android.util.FloatMath;
导入android.view.GestureDetector;
导入android.view.MotionEvent;
导入android.view.view;
导入android.view.view.OnTouchListener;
导入android.widget.ImageView;
公共类ScaleImageView扩展ImageView实现OnTouchListener{
静态最终浮动行程_宽度=10f;
静态最终浮动半行程宽度=行程宽度/2;
浮动lastTouchX;
浮触;
final RectF dirtyRect=new RectF();
私有上下文;
专用浮点数最大刻度=2f;
私有静态矩阵mMatrix;
私有最终浮动[]mMatrixValues=新浮动[9];
//显示宽度和高度。
私人英特姆维兹;
私营机构;
私有内部宽度;
私家车;
私人浮动mScale;
私人浮动货币;
私人浮动距离;
私有布尔标度;
私有int-mPrevMoveX;
私家车;
私人手势检测器;
油漆=新油漆();
公共静态路径路径=新路径();
公共静态int-imageheight、imagewidth;
String TAG=“ScaleImageView”;
公共ScaleImageView(上下文、属性集属性){
超级(上下文,attr);
this.mContext=上下文;
初始化();
}
公共ScaleImageView(上下文){
超级(上下文);
this.mContext=上下文;
初始化();
}
私有void resetDirtyRect(float-eventX,float-eventY){
dirtyRect.left=Math.min(lastTouchX,eventX);
dirtyRect.right=Math.max(lastTouchX,eventX);
dirtyRect.top=Math.min(lastTouchY,eventY);
dirtyRect.bottom=Math.max(lastTouchY,eventY);
}
@凌驾
公共void setImageBitmap(位图bm){
super.setImageBitmap(bm);
这是初始化();
}
@凌驾
公共void setImageResource(int resId){
super.setImageResource(resId);
这是初始化();
}
私有void初始化(){
此.setScaleType(ScaleType.MATRIX);
this.mMatrix=新矩阵();
Drawable d=getDrawable();
paint.setAntiAlias(真);
油漆。设置颜色(颜色。红色);
绘制.设置样式(绘制.样式.笔划);
绘制.设置行程连接(绘制.连接.圆形);
油漆。设置行程宽度(行程宽度);
如果(d!=null){
mIntrinsicWidth=d.getIntrinsicWidth();
mIntrinsicHeight=d.getIntrinsicHeight();
setOnTouchListener(这个);
}
mDetector=新的手势检测器(mContext,
新的GestureDetector.SimpleOnGestureListener(){
@凌驾
公共布尔onDoubleTap(运动事件e){
maxZoomTo((int)e.getX(),(int)e.getY());
切割();
返回super.onDoubleTap(e);
}
});
}
@凌驾
受保护的布尔集合框架(int l,int t,int r,int b){
mWidth=r-l;
mHeight=b-t;
mMatrix.reset();
int r_norm=r-l;
mScale=(float)r_norm/(float)mIntrinsicWidth;
int paddingHeight=0;
int paddingWidth=0;
//垂直缩放
如果(mScale*mIntrinsicHeight>mHeight){
mScale=(浮动)mhweight/(浮动)mIntrinsicHeight;
mMatrix.后量表(mScale,mScale);
填充宽度=(r-mWidth)/2;
填充高度=0;
//水平缩放
}否则{
mMatrix.后量表(mScale,mScale);
填充高度=(b-mhweight)/2;
填充宽度=0;
}
mMatrix.postTranslate(填充宽度、填充高度);
setImageMatrix(mMatrix);
mMinScale=mScale;
zoomTo(mScale,mWidth/2,mHweight/2);
切割();
返回super.setFrame(l,t,r,b);
}
受保护的浮点getValue(矩阵,int whichValue){
矩阵。获取值(mMatrixValues);
返回mMatrixValues[whichValue];
}
受保护的浮点getScale(){
返回getValue(mMatrix,Matrix.MSCALE_X);
}
公共浮点数getTranslateX(){
返回getValue(mMatrix,Matrix.MTRANS_X);
}
受保护的浮点getTranslateY(){
返回getValue(mMatrix,Matrix.MTRANS_Y);
}
受保护的无效maxZoomTo(整数x,整数y){
如果(mMinScale!=getScale()&(getScale()-mMinScale)>0.1f){
//阈值0.1f
浮动比例=mMinScale/getScale();
缩放(缩放,x,y);
}否则{
浮动刻度=最大刻度/getScale();
缩放(缩放,x,y);
}
}
公共空间缩放(浮动比例,整数x,整数y){
如果(getScale()*比例=1&&getSca
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <Button
        android:id="@+id/activity_main_zoom_zoom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Zoom" />

    <Button
        android:id="@+id/activity_main_zoom_draw"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Draw" />

    <Button
        android:id="@+id/activity_main_save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Save" />
</LinearLayout>

<com.matabii.dev.scaleimageview.ScaleImageView
    android:id="@+id/image"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:src="@drawable/sample" />

</LinearLayout>