如何裁剪位图



我已经从片段中检索了位图&我在Imageview中放置了位图(解码的字节数组),我想裁剪这个位图

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

    cropphoto = (ImageView)view.findViewById(R.id.cropphoto);
    title = (TextView)view.findViewById(R.id.title);
    title.setText("Crop");
    crop = (Button)view.findViewById(R.id.crop);
    cancel = (Button)view.findViewById(R.id.cancel);
    tmp = getArguments().getString("PHOTO");
    byte [] encodeByte=Base64.decode(tmp,Base64.DEFAULT);
    bmp=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
    cropphoto.setImageBitmap(bmp);
    Width = cropphoto.getWidth();
    Height = cropphoto.getHeight();

调用Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height)

请参阅参考资料。

使用此方法。

private void doCrop() {
    final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setType("image/*");
    List<ResolveInfo> list = getActivity().getPackageManager().queryIntentActivities(intent, 0);
    int size = list.size();
    if (size == 0) {
        Toast.makeText(getActivity(), "Can not find image crop app", Toast.LENGTH_SHORT).show();
        return;
    } else {
        intent.setData(Uri.fromFile(new File(mainActivity.mCommonMethod.getAppPath() + "/profile.png")));
        intent.putExtra("outputX", 256);
        intent.putExtra("outputY", 256);
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", true);
        if (size == 1) {
            Intent i = new Intent(intent);
            ResolveInfo res = list.get(0);
            i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
            startActivityForResult(i, CROP_FROM_CAMERA);
        } else {
            for (ResolveInfo res : list) {
                final CropOption co = new CropOption();
                co.title = getActivity().getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
                co.icon = getActivity().getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
                co.appIntent = new Intent(intent);
                co.appIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
                cropOptions.add(co);
            }
            CropOptionAdapter adapter = new CropOptionAdapter(getActivity().getApplicationContext(), cropOptions);
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle("Choose Crop App");
            builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int item) {
                    startActivityForResult(cropOptions.get(item).appIntent, CROP_FROM_CAMERA);
                }
            });
            builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    if (mImageCaptureUri != null) {
                        getActivity().getContentResolver().delete(mImageCaptureUri, null, null);
                        // mImageCaptureUri = null;
                        try {
                            bitmap = mainActivity.mCommonMethod.resizeBitmap(bitmap);
                            bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), mImageCaptureUri);
                        } catch (FileNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            });
            AlertDialog alert = builder.create();
            alert.show();
        }
    }
}

而不是使用默认的"com.android.caCamera.action.CROP"。我只想分享这段代码,它将为图像视图提供自定义裁剪或徒手裁剪活动。希望它能帮助你们。

首先你需要创建一个类似CropView 的类

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

我所做的是,我扩展了ImageView并添加了裁剪功能。它很容易使用。一旦保存了类,只需在布局中使用它,如下所示。

<"your package name".CropView
 android:id="@+id/image_preview"
 android:layout_width="fill_parent"
 android:layout_height="match_parent" />

在你的活动中称之为"作物视图",如下面的

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onCreate(savedInstanceState);
 setContentView(R.layout.crop_layout);

 myCropView = new CropView(this);
  tmp = getArguments().getString("PHOTO");
   byte [] encodeByte=Base64.decode(tmp,Base64.DEFAULT);
   bmp=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
   myCropView.setImageBitmap(bmp);
}

就是这样!希望它能有所帮助!如果您遇到任何问题,请随时询问:)

使用的系统裁剪:

private void doCrop() {
    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setType("image/*");
    List<ResolveInfo> list = getPackageManager().queryIntentActivities(
            intent, 0);
    int size = list.size();
    if (size == 0) {
        Toast.makeText(this, "Can not find image crop app",
                Toast.LENGTH_SHORT).show();
        return;
    } else {
        intent.setData(mImageCaptureUri);
        intent.putExtra("outputX", 180);
        intent.putExtra("outputY", 310);
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1.5f);
        intent.putExtra("crop", false);
        // intent.putExtra("scale", false);
        intent.putExtra("return-data", true);
        Intent i = new Intent(intent);
        ResolveInfo res = list.get(0);
        i.setComponent(new ComponentName(res.activityInfo.packageName,
                res.activityInfo.name));
        startActivityForResult(i, CROP_FROM_CAMERA);            
    }
}

经过很长一段时间,我得到了这样一个解决方案,只需使用Edmodo Library简单裁剪位图

最新更新