如何在片段中裁剪位图?

时间:2015-03-05 07:56:12

标签: android bitmap

请帮助解决这个问题...

First Fragment 这是1stFragment文件发送编码位图的字符串

    tmp = getArguments().getString("PHOTO");

      byte [] encodeByte=Base64.decode(tmp,Base64.DEFAULT);
      bmp=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);

      ByteArrayOutputStream b=new  ByteArrayOutputStream();
      bmp.compress(Bitmap.CompressFormat.PNG,100, b);
      bm =b.toByteArray();
      temp=Base64.encodeToString(bm, Base64.DEFAULT);Fragment fr = new CropToolActivity();
                        fm = getFragmentManager();
                        FragmentTransaction ft = fm.beginTransaction();
                        args = new Bundle();
                        args.putString("PHOTO", temp);
                        fr.setArguments(args);
                        ft.replace(R.id.frame,fr);
                        ft.commit();

CropToolActivity 这是一个2ndFragment文件,接收编码位图的字符串 还将CropView设置为布局

public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.croptool, container, false);

        myCropView = (CropView)view.findViewById(R.id.crop_tool);
        myCropView = new CropView(getActivity().getApplicationContext());

        tmp = getArguments().getString("PHOTO");

        byte [] encodeByte=Base64.decode(tmp,Base64.DEFAULT);
        bmp=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
        myCropView.setImageBitmap(bmp);

croptool.xml 这是第二个片段布局的XML文件          

    <com.tcss.photostyle.CropView
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:id="@+id/crop_tool" />

</LinearLayout>

CropView.Java

这是一个croptool java文件,用于演示位图上的Croptool

public class CropView extends ImageView {

Paint paint = new Paint();
private int initial_size = 300;
private static Point leftTop, rightBottom, center, previous;

private static final int DRAG= 0;
private static final int LEFT= 1;
private static final int TOP= 2;
private static final int RIGHT= 3;
private static final int BOTTOM= 4;

private int imageScaledWidth,imageScaledHeight;
// Adding parent class constructors   
public CropView(Context context) {
   super(context);
   initCropView();
 }

 public CropView(Context context, AttributeSet attrs) {
   super(context, attrs, 0);
   initCropView();
 }

 public CropView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  initCropView();
 }

 @Override
 protected void onDraw(Canvas canvas)
 {
   super.onDraw(canvas);
   if(leftTop.equals(0, 0))
      resetPoints();
  canvas.drawRect(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y, paint);
  }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  int eventaction = event.getAction();
  switch (eventaction) { 
      case MotionEvent.ACTION_DOWN:
          previous.set((int)event.getX(), (int)event.getY());
          break; 
     case MotionEvent.ACTION_MOVE: 
         if(isActionInsideRectangle(event.getX(), event.getY())) {
             adjustRectangle((int)event.getX(), (int)event.getY());
             invalidate(); // redraw rectangle
             previous.set((int)event.getX(), (int)event.getY());
         }
         break; 
     case MotionEvent.ACTION_UP: 
         previous = new Point();
         break;
 }         
  return true;
 }

 private void initCropView() {
  paint.setColor(Color.YELLOW);
  paint.setStyle(Style.STROKE);
  paint.setStrokeWidth(5);  
  leftTop = new Point();
 rightBottom = new Point();
 center = new Point();
 previous = new Point();
 }

public void resetPoints() {
   center.set(getWidth()/2, getHeight()/2);
   leftTop.set((getWidth()-initial_size)/2,(getHeight()-initial_size)/2);
   rightBottom.set(leftTop.x+initial_size, leftTop.y+initial_size);
 }

 private static boolean isActionInsideRectangle(float x, float y) {
  int buffer = 10;
  return (x>=(leftTop.x-buffer)&&x<=(rightBottom.x+buffer)&& y>=(leftTop.y-buffer)&&y<=(rightBottom.y+buffer))?true:false;
 }

 private boolean isInImageRange(PointF point) {
  // Get image matrix values and place them in an array
  float[] f = new float[9];
 getImageMatrix().getValues(f);

 // Calculate the scaled dimensions
  imageScaledWidth = Math.round(getDrawable().getIntrinsicWidth() * f[Matrix.MSCALE_X]);
  imageScaledHeight = Math.round(getDrawable().getIntrinsicHeight() * f[Matrix.MSCALE_Y]);

  return (point.x>=(center.x-(imageScaledWidth/2))&&point.x<=(center.x+(imageScaledWidth/2))&&point.y>=(center.y-(imageScaledHeight/2))&&point.y<=(center.y+(imageScaledHeight/2)))?true:false;
}

 private void adjustRectangle(int x, int y) {
  int movement;
  switch(getAffectedSide(x,y)) {
      case LEFT:
         movement = x-leftTop.x;
         if(isInImageRange(new  PointF(leftTop.x+movement,leftTop.y+movement)))
            leftTop.set(leftTop.x+movement,leftTop.y+movement);
        break;
      case TOP:
        movement = y-leftTop.y;
        if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement)))
            leftTop.set(leftTop.x+movement,leftTop.y+movement);
        break;
      case RIGHT:
        movement = x-rightBottom.x;
        if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement)))
            rightBottom.set(rightBottom.x+movement,rightBottom.y+movement);
        break;
     case BOTTOM:
        movement = y-rightBottom.y;
        if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement)))
            rightBottom.set(rightBottom.x+movement,rightBottom.y+movement);
        break;      
     case DRAG:
        movement = x-previous.x;
        int movementY = y-previous.y;
        if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movementY)) && isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movementY))) {
            leftTop.set(leftTop.x+movement,leftTop.y+movementY);
              rightBottom.set(rightBottom.x+movement,rightBottom.y+movementY);
        }
        break;
  }
}

  private static int getAffectedSide(float x, float y) {
   int buffer = 10;
   if(x>=(leftTop.x-buffer)&&x<=(leftTop.x+buffer))
    return LEFT;
   else if(y>=(leftTop.y-buffer)&&y<=(leftTop.y+buffer))
    return TOP;
   else if(x>=(rightBottom.x-buffer)&&x<=(rightBottom.x+buffer))
    return RIGHT;
   else if(y>=(rightBottom.y-buffer)&&y<=(rightBottom.y+buffer))
    return BOTTOM;
    else
     return DRAG;
   }

   public byte[] getCroppedImage() {
   BitmapDrawable drawable = (BitmapDrawable)getDrawable();
   float x = leftTop.x-center.x+(drawable.getBitmap().getWidth()/2);
   float y = leftTop.y-center.y+(drawable.getBitmap().getHeight()/2);
   Bitmap cropped = Bitmap.createBitmap(drawable.getBitmap(),(int)x,(int)y,(int)rightBottom.x-(int)leftTop.x,(int)rightBottom.y-(int)leftTop.y);
 ByteArrayOutputStream stream = new ByteArrayOutputStream();
 cropped.compress(Bitmap.CompressFormat.PNG, 100, stream);
  return stream.toByteArray();
  }
 }

1 个答案:

答案 0 :(得分:1)

这是一种从中心裁剪位图的方法,假设newWidth < bitmap.getWidth() and newHeight < bitmap.getHeight()

    public Bitmap cropBitmap(Bitmap bitmap, int newWidth, int newHeight) {
        double x = (bitmap.getWidth() - newWidth) / 2;
        double y = (bitmap.getHeight() - newHeight) / 2;

        Bitmap b = Bitmap.createBitmap((int)newWidth, (int)newHeight, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
        c.drawBitmap(bitmap, new Rect((int)x , (int)y, (int)(x + newWidth), (int)(y + newHeight)), new Rect(0, 0, (int)newWidth, (int)newHeight), null);
        return b;
    }