更改路径大小而不更改以前的路径

时间:2015-12-26 14:02:44

标签: java android

我有一个用于擦除背景的应用程序,我使用了一个搜索栏来改变橡皮擦的大小。但是当我改变SeekBar的进度时,之前的路径发生了变化。 我想更改路径大小而不更改以前的路径

主要活动

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.image_overlay_bitmap);

    scratchView = (WScratchView) findViewById(R.id.scratch_view);
    global = ((Global) getApplicationContext());
    scratchView.setRevealSize(1);
    SeekBar seekbar = (SeekBar) findViewById(R.id.myseek);
    seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub


        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            // TODO Auto-generated method stub


            scratchView.setRevealSize(progress);


                        }
    });



    if (getIntent().getExtras().getBoolean("isFromCrop")) {

        Log.i("width", "" + global.getBitmap().getWidth());
        Log.i("height", "" + global.getBitmap().getHeight());

        // set bitmap to scratchview
        // Bitmap bitmap =
        // BitmapFactory.decodeResource(getResources(),R.drawable.test);

        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        /*
         * int height = displaymetrics.heightPixels; int width =
         * displaymetrics.widthPixels;
         */

        int height = global.getBitmap().getHeight();
        int width = global.getBitmap().getWidth();

        Bitmap scaledBitmap = Bitmap.createBitmap(width, height,
                Config.ARGB_8888);

        float ratioX = width / (float) global.getBitmap().getWidth();
        float ratioY = height / (float) global.getBitmap().getHeight();
        float middleX = width / 2.0f;
        float middleY = height / 2.0f;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(global.getBitmap(), middleX
                - global.getBitmap().getWidth() / 2, middleY
                - global.getBitmap().getHeight() / 2, new Paint(
                Paint.FILTER_BITMAP_FLAG));
        i = seekbar.getProgress();
        scratchView.setRevealSize(i);





    } else {
        SharedPreferences settings = getApplicationContext()
                .getSharedPreferences("pref", 0);
        settings = getApplicationContext().getSharedPreferences("pref", 0);
        String picture = settings.getString("file_path", "");

        Bitmap mbitmap = BitmapFactory.decodeFile(picture);
        scratchView.setScratchBitmap(mbitmap);

    }

    /*
     * scratchView.setScratchBitmap(getResizedBitmap(global.getBitmap(),
     * width, height));
     */




//  scratchView.setOverlayColor(1);
    //i = seekbar.getProgress();
//  seekbar.setMax(100);


}

public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {

    int width = bm.getWidth();

    int height = bm.getHeight();

    float scaleWidth = ((float) newWidth) / width;

    float scaleHeight = ((float) newHeight) / height;

    Log.i("scalewidth", "" + scaleWidth);
    Log.i("scaleheight", "" + scaleHeight);

    // CREATE A MATRIX FOR THE MANIPULATION

    Matrix matrix = new Matrix();

    // RESIZE THE BIT MAP

    matrix.postScale(scaleWidth, scaleHeight);

    // RECREATE THE NEW BITMAP

    Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
            matrix, false);

    return resizedBitmap;

}

private File captureImage() {
    // TODO Auto-generated method stub
    OutputStream output;

    Calendar cal = Calendar.getInstance();

    Bitmap bitmap = Bitmap.createBitmap(scratchView.getWidth(),
            scratchView.getHeight(), Config.ARGB_8888);

    bitmap = ThumbnailUtils.extractThumbnail(bitmap,
            scratchView.getWidth(), scratchView.getHeight());

    Canvas b = new Canvas(bitmap);
    scratchView.draw(b);

    // Find the SD Card path
    File filepath = Environment.getExternalStorageDirectory();

    // Create a new folder in SD Card
    File dir = new File(filepath.getAbsolutePath() + "/demotemp/");
    dir.mkdirs();

    mImagename = "imageTemp" + ".png";

    // Create a name for the saved image
    file = new File(dir, mImagename);

    // Show a toast message on successful save
    Toast.makeText(ImageOverlayBitmap.this, "Image Saved to SD Card",
            Toast.LENGTH_SHORT).show();

    try {

        output = new FileOutputStream(file);
        // Compress into png format image from 0% - 100%
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
        output.flush();
        output.close();
    }

    catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return file;

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

public void onClickHandler(View view) {
    switch (view.getId()) {
    case R.id.reset_button:

        captureImage();

        SharedPreferences settings = getApplicationContext()
                .getSharedPreferences("pref", 0);
        settings = getApplicationContext().getSharedPreferences("pref", 0);
        SharedPreferences.Editor editor = settings.edit();
        editor.putString("file_path", file.getPath());
        editor.commit();

        Intent i = new Intent(ImageOverlayBitmap.this,
                SelectedImgActivity.class);
        global.setfile_path(file.getPath());
        i.putExtra("isBackgroundSet", false);
        startActivity(i);
        finish();

        // scratchView.resetView();
        break;
    }
} }

绘制活动

public WScratchView(Context ctx, AttributeSet attrs) {
    super(ctx, attrs);
    init(ctx, attrs);
}

public WScratchView(Context context) {
    super(context);
    init(context, null);
}

private void init(Context context, AttributeSet attrs) {
    mContext = context;

    // default value
    mOverlayColor = DEFAULT_COLOR;
    mRevealSize = DEFAULT_REVEAL_SIZE;



    setZOrderOnTop(true);
    SurfaceHolder holder = getHolder();
    holder.addCallback(this);
    holder.setFormat(PixelFormat.TRANSPARENT);

    mOverlayPaint = new Paint();
    mOverlayPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
    mOverlayPaint.setStyle(Paint.Style.STROKE);
    mOverlayPaint.setStrokeCap(Paint.Cap.ROUND);
    mOverlayPaint.setStrokeJoin(Paint.Join.ROUND);

    // convert drawable to bitmap if drawable already set in xml
    if (mScratchDrawable != null) {
        mScratchBitmap = ((BitmapDrawable) mScratchDrawable).getBitmap();
    }

    mBitmapPaint = new Paint();
    mBitmapPaint.setAntiAlias(true);
    mBitmapPaint.setFilterBitmap(true);
    mBitmapPaint.setDither(true);
}

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if (mScratchBitmap != null) {
        if (mMatrix == null) {
            float scaleWidth = (float) canvas.getWidth() / mScratchBitmap.getWidth();
            float scaleHeight = (float) canvas.getHeight() / mScratchBitmap.getHeight();
            mMatrix = new Matrix();
            mMatrix.postScale(scaleWidth, scaleHeight);
        }
        canvas.drawBitmap(mScratchBitmap, mMatrix, mBitmapPaint);
    } else {
        canvas.drawColor(mOverlayColor);
    }

    for (Path path : mPathList) {
        mOverlayPaint.setAntiAlias(mIsAntiAlias);
        mOverlayPaint.setStrokeWidth(mRevealSize);
        canvas.drawPath(path, mOverlayPaint);



    }


}

private void updateScratchedPercentage() {
    if(mOnScratchCallback == null) return;
    mOnScratchCallback.onScratch(getScratchedRatio());
}

@Override
public boolean onTouchEvent(MotionEvent me) {
    synchronized (mThread.getSurfaceHolder()) {
        if (!mIsScratchable) {
            return true;
        }

        switch (me.getAction()) {
        case MotionEvent.ACTION_DOWN:
            path = new Path();
            path.moveTo(me.getX(), me.getY());
            startX = me.getX();
            startY = me.getY();
            mPathList.add(path);

            break;
        case MotionEvent.ACTION_MOVE:
            //if (mScratchStart) {
            if (path.isEmpty()) {
                path.lineTo(me.getX(), me.getY());
            } else {
                if (isScratch(startX, me.getX(), startY, me.getY())) {
                    mScratchStart = true;


            }
        updateScratchedPercentage();
            break;
        case MotionEvent.ACTION_UP:
            mPathList.add(path);
        //  mScratchStart = false;
            break;
        }
        return true;
    }
}

private boolean isScratch(float oldX, float x, float oldY, float y) {
    float distance = (float) Math.sqrt(Math.pow(oldX - x, 2) + Math.pow(oldY - y, 2));
    if (distance > mRevealSize * 2) {
        return true;
    } else {
        return false;
    }
}

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
    // do nothing
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mScratchedTestBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    mScratchedTestCanvas = new Canvas(mScratchedTestBitmap); 
} 

@Override
public void surfaceCreated(SurfaceHolder arg0) {
    mThread = new WScratchViewThread(getHolder(), this);
    mThread.setRunning(true);
    mThread.start();

    mScratchedTestBitmap = Bitmap.createBitmap(arg0.getSurfaceFrame().width(), arg0.getSurfaceFrame().height(), Bitmap.Config.ARGB_8888);
    mScratchedTestCanvas = new Canvas(mScratchedTestBitmap);
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
    boolean retry = true;
    mThread.setRunning(false);
    while (retry) {
        try {
            mThread.join();
            retry = false;
        } catch (InterruptedException e) {
            // do nothing but keep retry
        }
    }

}

class WScratchViewThread extends Thread {
    private SurfaceHolder mSurfaceHolder;
    private WScratchView mView;
    private boolean mRun = false;

    public WScratchViewThread(SurfaceHolder surfaceHolder, WScratchView view) {
        mSurfaceHolder = surfaceHolder;
        mView = view;
    }

    public void setRunning(boolean run) {
        mRun = run;
    }

    public SurfaceHolder getSurfaceHolder() {
        return mSurfaceHolder;
    }

    @Override
    public void run() {
        Canvas c;
        while (mRun) {
            c = null;
            try {
                c = mSurfaceHolder.lockCanvas(null);
                synchronized (mSurfaceHolder) {
                    if (c != null) {
                        mView.draw(c);
                    }
                }
            } finally {
                if (c != null) {
                    mSurfaceHolder.unlockCanvasAndPost(c);
                }
            }
        }
    }
}

@Override
public void resetView() {
    synchronized (mThread.getSurfaceHolder()) {
        mPathList.clear();
    }
}

@Override
public boolean isScratchable() {
    return mIsScratchable;
}

@Override
public void setScratchable(boolean flag) {
    mIsScratchable = flag;
}

@Override
public void setOverlayColor(int ResId) {
    mOverlayColor = ResId;
}

@Override
public void setRevealSize(int size) {
    Canvas canvas = new Canvas();
    //mScratchedTestBitmap = Bitmap.createBitmap(mScratchedTestBitmap.getWidth(), mScratchedTestBitmap.getWidth(), Bitmap.Config.ARGB_8888);
    //mScratchedTestCanvas = new Canvas(mScratchedTestBitmap);
    canvas.drawBitmap(mScratchBitmap,mMatrix, mBitmapPaint);
    mRevealSize = size;
}

@Override
public void setAntiAlias(boolean flag) {
    mIsAntiAlias = flag;
}

@Override
public void setScratchDrawable(Drawable d) {
    mScratchDrawable = d;
    if (mScratchDrawable != null) {
        mScratchBitmap = ((BitmapDrawable) mScratchDrawable).getBitmap();
    }
}

@Override
public void setScratchBitmap(Bitmap b) {
    mScratchBitmap = b;
}

@Override
public float getScratchedRatio() {
    return getScratchedRatio(DEFAULT_SCRATCH_TEST_SPEED);
}

/**
 * thanks to https://github.com/daveyfong for providing this method
 */
@Override
public float getScratchedRatio(int speed) {
    if (null == mScratchedTestBitmap) {
        return 0;
    }
    draw(mScratchedTestCanvas);

    final int width = mScratchedTestBitmap.getWidth();
    final int height = mScratchedTestBitmap.getHeight();

    int count = 0;
    for (int i = 0; i < width; i += speed) {
        for (int j = 0; j < height; j += speed) {
            if (0 == Color.alpha(mScratchedTestBitmap.getPixel(i, j))) {
                count++;
            }
        }
    }
    float completed = (float) count / ((width / speed) * (height / speed)) * 100;

    return completed;
}

public void setOnScratchCallback(OnScratchCallback callback) {
    mOnScratchCallback = callback;
}

public static abstract class OnScratchCallback{
    public abstract void onScratch(float percentage);
}

@Override
public void setScratchAll(boolean scratchAll) {
    // TODO Auto-generated method stub

}

@Override
public void setBackgroundClickable(boolean clickable) {
    // TODO Auto-generated method stub

} }

1 个答案:

答案 0 :(得分:0)

我注意到,在onDraw()例程中,您将每个路径的笔触宽度设置为mRevealSize。此外,此mRevealSize是由SeekBar更改的内容。

我认为您需要做的是每次用户做出擦除路径时捕获笔划宽度mRevealSize,并将该笔划宽度存储在补充mPathList的列表中。那么您的onDraw()就会:

for (int i = 0; i < mPathList.size(); i++) {
    mOverlayPaint.setAntiAlias(mIsAntiAlias);
    mOverlayPaint.setStrokeWidth(mStrokeList.get(i));
    canvas.drawPath(mPathList.get(i), mOverlayPaint);
}