2015-12-26 262 views
0

我有一個用於擦除背景的應用程序,並且我使用了一個seekbar來更改橡皮擦的大小。但是當我改變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 

} } 

回答

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