2014-01-30 82 views
1

在我的应用程序中,我尝试从选定的用户形状裁剪位图。 我已阅读了很多关于这个问题,仍然无法找到任何解决方案。 剪裁后得到的图像不是我标记的图像。使用路径对象裁剪位图

这里是我的代码:

public class TestView extends ImageView implements OnTouchListener { 
    private Paint paint; 
    public static List<Point> points; 

    Bitmap bitmapMain; 

    Context mContext; 

    private int leftX = 0; 
    private int rightX = 0; 
    private int upY = 0; 
    private int downY = 0; 

    public TestView(Context c) { 
     super(c); 

     mContext = c; 
     setFocusable(true); 
     setFocusableInTouchMode(true); 

     paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setPathEffect(new DashPathEffect(new float[] { 10, 20 }, 0)); 
     paint.setStrokeWidth(5); 
     paint.setColor(Color.WHITE); 

     this.setOnTouchListener(this); 
     points = new ArrayList<Point>(); 


    } 

    public TestView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     mContext = context; 
     setFocusable(true); 
     setFocusableInTouchMode(true); 

     paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeWidth(2); 
     paint.setColor(Color.WHITE); 

     this.setOnTouchListener(this); 
     points = new ArrayList<Point>(); 

    } 

    public void setBitmap(Bitmap bit) 
    { 
     bitmapMain = bit; 
    } 

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

     // canvas.drawBitmap(bitmap, 0, 0, null); 

     Path path = new Path(); 
     boolean first = true; 

     for (int i = 0; i < points.size(); i += 2) { 
      Point point = points.get(i); 
      if (first) { 
       first = false; 
       path.moveTo(point.x, point.y); 
      } else if (i < points.size() - 1) { 
       Point next = points.get(i + 1); 
       path.quadTo(point.x, point.y, next.x, next.y); 
      } else { 
       path.lineTo(point.x, point.y); 
      } 
     } 
     canvas.drawPath(path, paint); 
    } 

    public boolean onTouch(View view, MotionEvent event) { 


     if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_OUTSIDE || event.getAction() == MotionEvent.ACTION_CANCEL) 
     { 
      return true; 
     } 

     int intX = (int) (event.getX()); 
     int intY = (int) (event.getY()); 

     if(event.getAction() == MotionEvent.ACTION_DOWN) 
     { 
      leftX = intX; 
      rightX = intX; 
      downY = intY; 
      upY = intY; 
     } 

     Point point = new Point(); 

     point.x = intX; 
     point.y = intY; 

     if(intX < leftX) 
      leftX = intX; 
     if(intX > rightX) 
      rightX = intX; 
     if(intY > downY) 
      downY = intY; 
     if(intY < upY) 
      upY = intY; 

     points.add(point); 


     invalidate(); 

     return true; 
    } 

    public void clear() 
    {  
     leftX = 0; 
     rightX = 0; 
     upY = 0; 
     downY = 0; 

     points.clear(); 
     paint.setColor(Color.WHITE); 
     paint.setStyle(Style.STROKE); 
     invalidate(); 
    } 


    public Bitmap getImage2() 
    { 

    //getting the size of the new bitmap 

     int newHeight = rightX - leftX; 
     int newWidth = downY - upY; 

     Bitmap resultingImage = Bitmap.createBitmap(newHeight, newWidth, Config.ARGB_8888); 

     Canvas canvas = new Canvas(resultingImage); 
     Paint paint = new Paint(); 
     paint.setAntiAlias(true); 

     Path path = new Path(); 
     for (int i = 0; i < points.size() - 1; i++) { 

      path.quadTo((float)points.get(i).x, (float)points.get(i).y, (float)points.get(i+1).x, (float)points.get(i+1).y); 
      // path.lineTo(points.get(i).x, points.get(i).y); 
     } 

//closing the shape, connection last point to the first one 

     path.quadTo((float)points.get(points.size()-1).x, (float)points.get(points.size()-1).y, (float)points.get(0).x, (float)points.get(0).y); 

     //drawing user shape 

     canvas.drawPath(path, paint); 

     //getting image inside the shape 

     paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); 

     canvas.drawBitmap(bitmapMain, 0, 0, paint); 

     return resultingImage; 
    } 



    } 

我的活动:

public class MainActivity extends Activity implements OnClickListener { 

    private TestView drawing; 
    private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100; 
    public static final int MEDIA_TYPE_IMAGE = 1; 
    private static final String IMAGE_DIRECTORY_NAME = "demo pictures"; 
    private Uri fileUri; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     this.requestWindowFeature(Window.FEATURE_NO_TITLE); 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     //drawing = (SignatureViewModed) findViewById(R.id.myTest); 
     findViewById(R.id.button1).setOnClickListener(this); 
     findViewById(R.id.button2).setOnClickListener(this); 
     findViewById(R.id.button3).setOnClickListener(this); 

     drawing = (TestView) findViewById(R.id.images); 

    } 

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



    @Override 
    public void onClick(View arg0) { 
     // TODO Auto-generated method stub 

     switch(arg0.getId()) 
     { 

     case R.id.button1: 
     { 
      drawing.clear(); 
      break; 
     } 

     case R.id.button2: 
     { 
      if(isDeviceSupportCamera()) 
       captureImage(); 
      else 
       Toast.makeText(this, "No camera", Toast.LENGTH_SHORT).show(); 
      break; 
     } 

     case R.id.button3: 
     { 
      showCutImage(); 
      break; 
     } 

     } 

    } 

    private boolean isDeviceSupportCamera() { 
     if (getApplicationContext().getPackageManager().hasSystemFeature(
       PackageManager.FEATURE_CAMERA)) { 
      // this device has a camera 
      return true; 
     } else { 
      // no camera on this device 
      return false; 
     } 
    } 

    private void captureImage() { 

     Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 

     fileUri = getOutputMediaFileUri(); 

     intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); 

     // start the image capture Intent 
     startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE); 
    } 

    public Uri getOutputMediaFileUri() { 
     return Uri.fromFile(getOutputMediaFile()); 
    } 

    /** 
    * returning image/video 
    */ 
    private static File getOutputMediaFile() { 

     // External sdcard location 
     File mediaStorageDir = new File(
       Environment 
         .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), 
       IMAGE_DIRECTORY_NAME); 

     // Create the storage directory if it does not exist 
     if (!mediaStorageDir.exists()) { 
      if (!mediaStorageDir.mkdirs()) { 
       Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create " 
         + IMAGE_DIRECTORY_NAME + " directory"); 
       return null; 
      } 
     } 

     // Create a media file name 
     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", 
       Locale.getDefault()).format(new Date()); 
     File mediaFile; 

     mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"); 

     return mediaFile; 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 

     // save file url in bundle as it will be null on scren orientation 
     // changes 
     outState.putParcelable("file_uri", fileUri); 
    } 

    @Override 
    protected void onRestoreInstanceState(Bundle savedInstanceState) { 
     super.onRestoreInstanceState(savedInstanceState); 

     // get the file url 
     fileUri = savedInstanceState.getParcelable("file_uri"); 
    } 


    @Override 
    protected void onActivityResult(int requestCode, int resultCode, 
      Intent data2) { 

     Bitmap bitmap = null; 

     if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) { 

      if (resultCode == RESULT_OK) 
      { 

       String filePath = fileUri.getPath(); 
       bitmap = decodeSampledBitmapFromPath(filePath, true); 

       drawing.setBitmap(bitmap); 

       drawing.setImageBitmap(bitmap); 
      } 

     } 

      super.onActivityResult(requestCode, resultCode, data2); 
     } 

    public Bitmap decodeSampledBitmapFromPath(String path, boolean isFullScreen) { 

     Bitmap bmp = null; 
     final BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 

     BitmapFactory.decodeFile(path, options); 

     if(isFullScreen) 
      options.inSampleSize = calculateInSampleSize(options, getScreenWidth() , getScreenHeight()); 
     else 
      options.inSampleSize = calculateInSampleSize(options, 200, 200); 

     // Decode bitmap with inSampleSize set 
     options.inJustDecodeBounds = false; 
     bmp = BitmapFactory.decodeFile(path, options); 

     return bmp; 
     } 

    public int calculateInSampleSize(BitmapFactory.Options options, 
      int reqWidth, int reqHeight) { 

     final int height = options.outHeight; 
     final int width = options.outWidth; 
     int inSampleSize = 1; 

     if (height > reqHeight || width > reqWidth) { 
      if (width > height) { 
       inSampleSize = Math.round((float) height/(float) reqHeight); 
      } else { 
       inSampleSize = Math.round((float) width/(float) reqWidth); 
      } 
     } 
     return inSampleSize; 
     } 

    @SuppressLint("NewApi") 
    public int getScreenHeight() 
    { 
     Display display = ((WindowManager) this.getSystemService(WINDOW_SERVICE)) 
       .getDefaultDisplay(); 

     int height = 0; 

     if (android.os.Build.VERSION.SDK_INT >= 13) { 
      Point size = new Point(); 
      display.getSize(size); 
      height = size.y; 

     } else { 
      height = display.getHeight(); 

     } 

     return height; 
    } 

    @SuppressLint("NewApi") 
    public int getScreenWidth() 
    { 
     Display display = ((WindowManager) this.getSystemService(WINDOW_SERVICE)) 
       .getDefaultDisplay(); 

     int width = 0; 

     if (android.os.Build.VERSION.SDK_INT >= 13) { 
      Point size = new Point(); 
      display.getSize(size); 

      width = size.x; 
     } else { 

      width = display.getWidth(); 
     } 

     return width; 
    } 

    public void showCutImage() 
    { 
     AlertDialog.Builder builder = new AlertDialog.Builder(this); 

     View prefView = View.inflate(this,R.layout.image_show, null); 

     ImageView image = (ImageView) prefView.findViewById(R.id.imageView1); 

     image.setImageBitmap(drawing.getImage2()); 

     builder.setView(prefView); 

     builder.show(); 

    } 

这里是我的结果的2张图片。 你可以看到我得到的图片不是我标记的整个区域,并且它有额外的角落。

enter image description here

enter image description here

+0

我没有analize你长的代码,但与路径种植非常简单:canvas.clipPath(...); canvas.draw *(...) – pskink

+0

嗨,我试过你的解决方案,但它不工作。 – dasdasd

+0

clipPath不工作?嗯... – pskink

回答

0

你应该关闭的路径。 更改testView的方法的onDraw到

公共无效的onDraw(帆布帆布){ super.onDraw(帆布);

// canvas.drawBitmap(bitmap, 0, 0, null); 

    Path path = new Path(); 
    boolean first = true; 

    for (int i = 0; i < points.size(); i += 2) { 
     Point point = points.get(i); 
     if (first) { 
      first = false; 
      path.moveTo(point.x, point.y); 
     } else if (i < points.size() - 1) { 
      Point next = points.get(i + 1); 
      path.quadTo(point.x, point.y, next.x, next.y); 
     } else { 
      path.lineTo(point.x, point.y); 
     } 
    } 
    path.lineTo(points.get(0).x,points.get(0).y); 
    canvas.drawPath(path, paint); 
}