【问题标题】:How to crop Bitmap?如何裁剪位图?
【发布时间】:2015-05-05 07:17:36
【问题描述】:

我已经从片段中检索位图并在 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();

【问题讨论】:

    标签: android


    【解决方案1】:

    经过很长时间,我得到了这样一个解决方案,即使用 Edmodo Library for Simple Crop your Bitmap...

    【讨论】:

    • 请将您的解决方案作为答案发布或使用新的详细信息更新您的问题。仅仅声明您已经找到了解决方案并不能真正为可能正在寻求解决同一问题的其他用户增加任何价值。
    【解决方案2】:

    二手系统作物:

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

    【讨论】:

      【解决方案3】:

      而不是使用默认的“com.android.camera.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);
      
      }
      

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

      【讨论】:

      • 我在 Activity 中得到黄色矩形,但是......我无法得到位图图像,而且......当我触摸矩形来调整大小时,应用程序崩溃了。,.
      • 您遇到了哪个错误?你能发布你的日志消息吗
      • 请查看我的完整代码...stackoverflow.com/questions/28872694/…...
      • 感谢 Gangulian 的帮助...但请再解决一个问题...上面链接中给出了哪个链接
      • 如果裁剪是有效的方法,您可以轻松地在您的情况下执行此操作。无关紧要的活动/片段。
      【解决方案4】:

      使用这个方法。

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

      【讨论】:

        【解决方案5】:

        致电Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height)

        reference

        【讨论】:

          猜你喜欢
          • 2019-05-10
          • 2013-08-16
          • 2015-12-11
          • 2013-03-25
          • 2017-10-19
          • 2012-02-29
          • 2012-08-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多