Пример #1
0
  private void initViews() {
    imageView = (CropImageView) findViewById(R.id.crop_image);
    imageView.context = this;
    imageView.setRecycler(
        new ImageViewTouchBase.Recycler() {

          @Override
          public void recycle(Bitmap b) {
            b.recycle();
            System.gc();
          }
        });

    findViewById(R.id.btn_cancel)
        .setOnClickListener(
            new View.OnClickListener() {

              public void onClick(View v) {
                setResult(RESULT_CANCELED);
                finish();
              }
            });

    findViewById(R.id.btn_done)
        .setOnClickListener(
            new View.OnClickListener() {

              public void onClick(View v) {
                onSaveClicked();
              }
            });
  }
  private void setupViews() {
    setContentView(R.layout.crop__activity_crop);

    imageView = (CropImageView) findViewById(R.id.crop_image);
    imageView.context = this;
    imageView.setRecycler(
        new ImageViewTouchBase.Recycler() {
          @Override
          public void recycle(Bitmap b) {
            b.recycle();
            System.gc();
          }
        });

    findViewById(R.id.btn_cancel)
        .setOnClickListener(
            new View.OnClickListener() {
              public void onClick(View v) {
                setResult(RESULT_CANCELED);
                finish();
              }
            });

    findViewById(R.id.btn_done)
        .setOnClickListener(
            new View.OnClickListener() {
              public void onClick(View v) {
                onSaveClicked();
              }
            });

    findViewById(R.id.btn_rotate_left)
        .setOnClickListener(
            new View.OnClickListener() {
              public void onClick(View v) {
                Bitmap bitmap = drawableToBitmap(imageView.getDrawable());
                rotateDegreesCounter = rotateDegreesCounter - 90;
                rotateBitmap = new RotateBitmap(bitmap, rotateDegreesCounter);
                if (rotateBitmap != null) {
                  startCrop();
                }
              }
            });

    findViewById(R.id.btn_rotate_right)
        .setOnClickListener(
            new View.OnClickListener() {

              public void onClick(View v) {

                Bitmap bitmap = drawableToBitmap(imageView.getDrawable());
                rotateDegreesCounter = rotateDegreesCounter + 90;
                rotateBitmap = new RotateBitmap(bitmap, rotateDegreesCounter);
                if (rotateBitmap != null) {
                  startCrop();
                }
              }
            });
  }
Пример #3
0
  /*
   * TODO This should use the decode/crop/encode single step API so that the whole (possibly large) Bitmap doesn't need to be read
   * into memory
   */
  private void onSaveClicked() {
    if (cropView == null || isSaving) {
      return;
    }
    isSaving = true;

    Bitmap croppedImage = null;
    Rect r = cropView.getScaledCropRect(sampleSize);
    int width = r.width();
    int height = r.height();

    int outWidth = width, outHeight = height;
    if (maxX > 0 && maxY > 0 && (width > maxX || height > maxY)) {
      float ratio = (float) width / (float) height;
      if ((float) maxX / (float) maxY > ratio) {
        outHeight = maxY;
        outWidth = (int) ((float) maxY * ratio + .5f);
      } else {
        outWidth = maxX;
        outHeight = (int) ((float) maxX / ratio + .5f);
      }
    }

    if (IN_MEMORY_CROP && rotateBitmap != null) {
      croppedImage =
          inMemoryCrop(rotateBitmap, croppedImage, r, width, height, outWidth, outHeight);
      if (croppedImage != null) {
        imageView.setImageBitmapResetBase(croppedImage, true);
        imageView.center(true, true);
        imageView.highlightViews.clear();
      }
    } else {
      try {
        croppedImage = decodeRegionCrop(croppedImage, r);
        if (isCircleCrop) {
          croppedImage = cropCircleView(croppedImage);
        }
      } catch (IllegalArgumentException e) {
        setResultException(e);
        finish();
        return;
      }

      if (croppedImage != null) {
        imageView.setImageRotateBitmapResetBase(new RotateBitmap(croppedImage, exifRotation), true);
        imageView.center(true, true);
        imageView.highlightViews.clear();
      }
    }
    saveImage(croppedImage);
  }
Пример #4
0
  private void startCrop() {
    if (isFinishing()) {
      return;
    }
    imageView.setImageRotateBitmapResetBase(rotateBitmap, true);
    CropUtil.startBackgroundJob(
        this,
        null,
        getResources().getString(R.string.crop__wait),
        new Runnable() {

          public void run() {
            final CountDownLatch latch = new CountDownLatch(1);
            handler.post(
                new Runnable() {

                  public void run() {
                    if (imageView.getScale() == 1F) {
                      imageView.center(true, true);
                    }
                    latch.countDown();
                  }
                });
            try {
              latch.await();
            } catch (InterruptedException e) {
              throw new RuntimeException(e);
            }
            new Cropper().crop();
          }
        },
        handler);
  }
Пример #5
0
        public void run() {
          mImageMatrix = mImageView.getImageMatrix();
          Bitmap faceBitmap = prepareBitmap();

          mScale = 1.0F / mScale;
          if (faceBitmap != null) {
            FaceDetector detector =
                new FaceDetector(faceBitmap.getWidth(), faceBitmap.getHeight(), mFaces.length);
            mNumFaces = detector.findFaces(faceBitmap, mFaces);
          }

          if (faceBitmap != null && faceBitmap != mBitmap) {
            faceBitmap.recycle();
          }

          mHandler.post(
              new Runnable() {
                public void run() {
                  mWaitingToPick = mNumFaces > 1;
                  makeDefault();
                  mImageView.invalidate();
                  if (mImageView.mHighlightViews.size() > 0) {
                    mCrop = mImageView.mHighlightViews.get(0);
                    mCrop.setFocus(true);
                  }

                  if (mNumFaces > 1) {}
                }
              });
        }
        // Create a default HightlightView if we found no face in the picture.
        private void makeDefault() {
          HighlightView hv = new HighlightView(mImageView, mOutlineColor, mOutlineCircleColor);

          int width = mBitmap.getWidth();
          int height = mBitmap.getHeight();

          Rect imageRect = new Rect(0, 0, width, height);

          // make the default size about 4/5 of the width or height
          int cropWidth = Math.min(width, height) * 4 / 5;
          int cropHeight = cropWidth;

          if (mAspectX != 0 && mAspectY != 0) {
            if (mAspectX > mAspectY) {
              cropHeight = cropWidth * mAspectY / mAspectX;
            } else {
              cropWidth = cropHeight * mAspectX / mAspectY;
            }
          }

          int x = (width - cropWidth) / 2;
          int y = (height - cropHeight) / 2;

          RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight);
          hv.setup(mImageMatrix, imageRect, cropRect, mCircleCrop, mAspectX != 0 && mAspectY != 0);
          mImageView.add(hv);
        }
Пример #7
0
 private void clearImageView() {
   imageView.clear();
   if (rotateBitmap != null) {
     rotateBitmap.recycle();
   }
   System.gc();
 }
  private void makeDefault() {
    HighlightView hv = new HighlightView(mImageView);

    int width = 0;
    int height = 0;
    if (mBitmap != null) {
      width = mBitmap.getWidth();
      height = mBitmap.getHeight();
    }

    Rect imageRect = new Rect(0, 0, width, height);

    // make the default size about 4/5 of the width or height
    int cropWidth = Math.min(width, height) * 4 / 5;
    int cropHeight = cropWidth;

    if (mAspectX != 0 && mAspectY != 0) {
      if (mAspectX > mAspectY) {
        cropHeight = cropWidth * mAspectY / mAspectX;
      } else {
        cropWidth = cropHeight * mAspectX / mAspectY;
      }
    }

    int x = (width - cropWidth) / 2;
    int y = (height - cropHeight) / 2;

    RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight);
    hv.setup(null, imageRect, cropRect, mCircleCrop, mAspectX != 0 && mAspectY != 0);
    mImageView.add(hv);
    hv.setResizeDrawable(mResizeDrawableWidth, mResizeDrawableHeight, mResizeDrawableDiagonal);
  }
Пример #9
0
 /**
  * Instantiates a new crop image.
  *
  * @param context the context
  * @param imageView the image view
  * @param handler the handler
  */
 public CropImage(Context context, CropImageView imageView, Handler handler) {
   mContext = context;
   mImageView = imageView;
   mImageView.setCropImage(this);
   mHandler = handler;
   // 初始化图片保存路径
   FILE_LOCAL = new File(AbFileUtil.getImageDownloadDir(context));
   if (!FILE_LOCAL.exists()) {
     FILE_LOCAL.mkdirs();
   }
 }
Пример #10
0
  @Override
  protected void onDestroy() {
    super.onDestroy();

    if (null != mImageView) {
      mImageView.clear();
    }
    if (null != mBitmap) {
      if (!mBitmap.isRecycled()) {
        mBitmap.recycle();
      }
      mBitmap = null;
    }
  }
        public void run() {
          mImageMatrix = mImageView.getImageMatrix();
          Bitmap faceBitmap = prepareBitmap();

          mScale = 1.0F / mScale;
          if (faceBitmap != null && mDoFaceDetection) {
            FaceDetector detector =
                new FaceDetector(faceBitmap.getWidth(), faceBitmap.getHeight(), mFaces.length);
            mNumFaces = detector.findFaces(faceBitmap, mFaces);
          }

          if (faceBitmap != null && faceBitmap != mBitmap) {
            faceBitmap.recycle();
          }

          mHandler.post(
              new Runnable() {
                public void run() {
                  mWaitingToPick = mNumFaces > 1;
                  if (mNumFaces > 0) {
                    for (int i = 0; i < mNumFaces; i++) {
                      handleFace(mFaces[i]);
                    }
                  } else {
                    makeDefault();
                  }
                  mImageView.invalidate();
                  if (mImageView.mHighlightViews.size() == 1) {
                    mCrop = mImageView.mHighlightViews.get(0);
                    mCrop.setFocus(true);
                  }

                  if (mNumFaces > 1) {
                    Toast t =
                        Toast.makeText(
                            CropImageBaseActivity.this,
                            R.string.multiface_crop_help,
                            Toast.LENGTH_SHORT);
                    t.show();
                  }
                }
              });
        }
  private void startFaceDetection() {
    if (isFinishing()) {
      return;
    }

    mImageView.setImageBitmapResetBase(mBitmap, true);

    Util.startBackgroundJob(
        this,
        this,
        null,
        getResources().getString(R.string.runningFaceDetection),
        new Runnable() {
          public void run() {
            final CountDownLatch latch = new CountDownLatch(1);
            final Bitmap b =
                (mImage != null)
                    ? mImage.fullSizeBitmap(IImage.UNCONSTRAINED, 1024 * 1024)
                    : mBitmap;
            mHandler.post(
                new Runnable() {
                  public void run() {
                    if (b != mBitmap && b != null) {
                      mImageView.setImageBitmapResetBase(b, true);
                      mBitmap.recycle();
                      mBitmap = b;
                    }
                    if (mImageView.getScale() == 1F) {
                      mImageView.center(true, true);
                    }
                    latch.countDown();
                  }
                });
            try {
              latch.await();
            } catch (InterruptedException e) {
              throw new RuntimeException(e);
            }
            mRunFaceDetection.run();
          }
        },
        mHandler);
  }
Пример #13
0
        // Create a default HightlightView if we found no face in the picture.
        private void makeDefault() {
          HighlightView hv = new HighlightView(mImageView);

          int width = mBitmap.getWidth();
          int height = mBitmap.getHeight();

          Rect imageRect = new Rect(0, 0, width, height);

          // CR: sentences!
          // make the default size about 4/5 of the width or height
          int cropWidth = Math.min(width, height) * 4 / 5;
          int cropHeight = cropWidth;

          int x = (width - cropWidth) / 2;
          int y = (height - cropHeight) / 2;

          RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight);
          hv.setup(mImageMatrix, imageRect, cropRect, false, true);
          mImageView.add(hv);
        }
Пример #14
0
        // For each face, we create a HightlightView for it.
        private void handleFace(FaceDetector.Face f) {
          PointF midPoint = new PointF();

          int r = ((int) (f.eyesDistance() * mScale)) * 2;
          f.getMidPoint(midPoint);
          midPoint.x *= mScale;
          midPoint.y *= mScale;

          int midX = (int) midPoint.x;
          int midY = (int) midPoint.y;

          HighlightView hv = new HighlightView(mImageView);

          int width = mBitmap.getWidth();
          int height = mBitmap.getHeight();

          Rect imageRect = new Rect(0, 0, width, height);

          RectF faceRect = new RectF(midX, midY, midX, midY);
          faceRect.inset(-r, -r);
          if (faceRect.left < 0) {
            faceRect.inset(-faceRect.left, -faceRect.left);
          }

          if (faceRect.top < 0) {
            faceRect.inset(-faceRect.top, -faceRect.top);
          }

          if (faceRect.right > imageRect.right) {
            faceRect.inset(faceRect.right - imageRect.right, faceRect.right - imageRect.right);
          }

          if (faceRect.bottom > imageRect.bottom) {
            faceRect.inset(faceRect.bottom - imageRect.bottom, faceRect.bottom - imageRect.bottom);
          }

          hv.setup(mImageMatrix, imageRect, faceRect, false, true);

          mImageView.add(hv);
        }
Пример #15
0
  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    mContentResolver = getContentResolver();

    requestWindowFeature(Window.FEATURE_NO_TITLE);

    // MenuHelper.showStorageToast(this);

    Intent intent = getIntent();
    Bundle extras = intent.getExtras();

    if (extras != null) {
      // if (extras.getString("circleCrop") != null) {
      // mCircleCrop = true;
      // mAspectX = 1;
      // mAspectY = 1;
      // }
      mSaveUri = (Uri) extras.getParcelable(MediaStore.EXTRA_OUTPUT);
      if (mSaveUri != null) {
        String outputFormatString = extras.getString("outputFormat");
        if (outputFormatString != null) {
          mOutputFormat = Bitmap.CompressFormat.valueOf(outputFormatString);
        }
      } else {
        mSetWallpaper = extras.getBoolean("setWallpaper");
      }
      mBitmap = (Bitmap) extras.getParcelable("data");
      mAspectX = extras.getInt("aspectX");
      mAspectY = extras.getInt("aspectY");
      mOutputX = extras.getInt("outputX");
      mOutputY = extras.getInt("outputY");
      mScale = extras.getBoolean("scale", false);
      mScaleUp = extras.getBoolean("scaleUpIfNeeded", false);
      // mDoFaceDetection = extras.containsKey("noFaceDetection")
      // ? !extras.getBoolean("noFaceDetection")
      // : true;

      android.content.res.Resources resources = getResources();
      int id = extras.getInt("arrowHorizontal", -1);
      if (id != -1) {
        mResizeDrawableWidth = resources.getDrawable(id);
      }
      id = extras.getInt("arrowVertical", -1);
      if (id != -1) {
        mResizeDrawableHeight = resources.getDrawable(id);
      }
      // id = extras.getInt("arrowDiagonal", -1);
      // if(id != -1){
      // mResizeDrawableDiagonal = resources.getDrawable(id);
      // }
    }

    if (mBitmap == null) {
      Uri target = intent.getData();
      try {
        decodeBitmapStreamSafe(target);
      } catch (OutOfMemoryError e) {
        OutOfMemoryHandler.handle();
      } catch (Throwable e) {
        e.printStackTrace();
      }
      // TODO
      // if (mImage != null) {
      // // Don't read in really large bitmaps. Use the (big) thumbnail
      // // instead.
      // // TODO when saving the resulting bitmap use the
      // // decode/crop/encode api so we don't lose any resolution.
      // mBitmap = mImage.thumbBitmap(IImage.ROTATE_AS_NEEDED);
      // }
    }

    if (mBitmap == null) {
      setResult(RESULT_CANCELED);
      finish();
      return;
    }

    // Make UI fullscreen.
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.cropimage);

    mImageView = (CropImageView) findViewById(R.id.image);
    findViewById(R.id.discard)
        .setOnClickListener(
            new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                setResult(RESULT_CANCELED);
                finish();
              }
            });

    findViewById(R.id.crop)
        .setOnClickListener(
            new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                onSaveClicked();
              }
            });

    final Button btn = (Button) findViewById(R.id.no_crop);
    btn.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            // if (mNeedCrop)
            // {
            // mImageView.setImageBitmapResetBase(mBitmap, true);
            // mImageView.remove(mCrop);
            // mCrop = null;
            //
            // btn.setText(R.string.crop_text);
            // }
            // else
            // {
            // makeDefault();
            // mImageView.requestLayout();
            // mCrop = mImageView.mHighlightViews.get(0);
            // mCrop.setFocus(true);
            //
            // btn.setText(R.string.no_crop_text);
            // }
            // mNeedCrop = !mNeedCrop;
            mNeedCrop = false;
            onSaveClicked();
          }
        });

    // startFaceDetection();
    mImageView.setImageBitmapResetBase(mBitmap, true);
    makeDefault();
    mCrop = mImageView.mHighlightViews.get(0);
    mCrop.setFocus(true);
  }
  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    mContentResolver = getContentResolver();

    setContentView(getContentViewId());

    mImageView = getCropImageView();

    // Work-around for devices incapable of using hardware-accelerated clipPath.
    // (android.view.GLES20Canvas.clipPath)
    //
    // See also:
    // - https://code.google.com/p/android/issues/detail?id=20474
    // - https://github.com/lvillani/android-cropimage/issues/20
    //
    if (Build.VERSION.SDK_INT > 10
        && Build.VERSION.SDK_INT < 16) { // >= Gingerbread && < Jelly Bean
      mImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    Intent intent = getIntent();
    Bundle extras = intent.getExtras();

    if (extras != null) {
      if (extras.getBoolean("circleCrop", false)) {
        mCircleCrop = true;
        mAspectX = 1;
        mAspectY = 1;
        mOutputFormat = Bitmap.CompressFormat.PNG;
      }
      mSaveUri = (Uri) extras.getParcelable(MediaStore.EXTRA_OUTPUT);
      if (mSaveUri != null) {
        String outputFormatString = extras.getString("outputFormat");
        if (outputFormatString != null) {
          mOutputFormat = Bitmap.CompressFormat.valueOf(outputFormatString);
        }
        mOutputQuality = extras.getInt("outputQuality", 100);
      } else {
        mSetWallpaper = extras.getBoolean("setWallpaper");
      }
      mBitmap = (Bitmap) extras.getParcelable("data");
      mAspectX = extras.getInt("aspectX");
      mAspectY = extras.getInt("aspectY");
      mOutputX = extras.getInt("outputX");
      mOutputY = extras.getInt("outputY");
      mOutlineColor = extras.getInt("outlineColor", HighlightView.DEFAULT_OUTLINE_COLOR);
      mOutlineCircleColor =
          extras.getInt("outlineCircleColor", HighlightView.DEFAULT_OUTLINE_CIRCLE_COLOR);
      mScale = extras.getBoolean("scale", true);
      mScaleUp = extras.getBoolean("scaleUpIfNeeded", true);
      mDoFaceDetection =
          extras.containsKey("noFaceDetection") ? !extras.getBoolean("noFaceDetection") : true;
    }

    if (mBitmap == null) {
      Uri target = intent.getData();
      mAllImages =
          ImageManager.makeImageList(mContentResolver, target, ImageManager.SORT_ASCENDING);
      mImage = mAllImages.getImageForUri(target);
      if (mImage != null) {
        // Don't read in really large bitmaps. Use the (big) thumbnail
        // instead.
        // TODO when saving the resulting bitmap use the
        // decode/crop/encode api so we don't lose any resolution.
        mBitmap = mImage.thumbBitmap(IImage.ROTATE_AS_NEEDED);
      }
    }

    if (mBitmap == null) {
      finish();
      return;
    }

    // Make UI fullscreen.
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

    Button discardButton = getDiscardButton();
    if (discardButton != null) {
      discardButton.setOnClickListener(
          new View.OnClickListener() {
            public void onClick(View v) {
              setResult(RESULT_CANCELED);
              finish();
            }
          });
    }

    Button saveButton = getSaveButton();
    if (saveButton != null) {
      saveButton.setOnClickListener(
          new View.OnClickListener() {
            public void onClick(View v) {
              onSaveClicked();
            }
          });
    }

    startFaceDetection();
  }
  private void onSaveClicked() {
    // TODO this code needs to change to use the decode/crop/encode single
    // step api so that we don't require that the whole (possibly large)
    // bitmap doesn't have to be read into memory
    if (mCrop == null) {
      return;
    }

    if (mSaving) return;
    mSaving = true;

    Bitmap croppedImage;

    // If the output is required to a specific size, create an new image
    // with the cropped image in the center and the extra space filled.
    if (mOutputX != 0 && mOutputY != 0 && !mScale) {
      // Don't scale the image but instead fill it so it's the
      // required dimension
      croppedImage = Bitmap.createBitmap(mOutputX, mOutputY, Bitmap.Config.RGB_565);
      Canvas canvas = new Canvas(croppedImage);

      Rect srcRect = mCrop.getCropRect();
      Rect dstRect = new Rect(0, 0, mOutputX, mOutputY);

      int dx = (srcRect.width() - dstRect.width()) / 2;
      int dy = (srcRect.height() - dstRect.height()) / 2;

      // If the srcRect is too big, use the center part of it.
      srcRect.inset(Math.max(0, dx), Math.max(0, dy));

      // If the dstRect is too big, use the center part of it.
      dstRect.inset(Math.max(0, -dx), Math.max(0, -dy));

      // Draw the cropped bitmap in the center
      canvas.drawBitmap(mBitmap, srcRect, dstRect, null);

      // Release bitmap memory as soon as possible
      mImageView.clear();
      mBitmap.recycle();
    } else {
      Rect r = mCrop.getCropRect();

      int width = r.width();
      int height = r.height();

      // If we are circle cropping, we want alpha channel, which is the
      // third param here.
      croppedImage =
          Bitmap.createBitmap(
              width, height, mCircleCrop ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);

      Canvas canvas = new Canvas(croppedImage);
      Rect dstRect = new Rect(0, 0, width, height);
      canvas.drawBitmap(mBitmap, r, dstRect, null);

      // Release bitmap memory as soon as possible
      mImageView.clear();
      mBitmap.recycle();

      if (mCircleCrop) {
        // OK, so what's all this about?
        // Bitmaps are inherently rectangular but we want to return
        // something that's basically a circle.  So we fill in the
        // area around the circle with alpha.  Note the all important
        // PortDuff.Mode.CLEAR.
        Canvas c = new Canvas(croppedImage);
        Path p = new Path();
        p.addCircle(width / 2F, height / 2F, width / 2F, Path.Direction.CW);
        c.clipPath(p, Region.Op.DIFFERENCE);
        c.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
      }

      // If the required dimension is specified, scale the image.
      if (mOutputX != 0 && mOutputY != 0 && mScale) {
        croppedImage =
            Util.transform(
                new Matrix(), croppedImage, mOutputX, mOutputY, mScaleUp, Util.RECYCLE_INPUT);
      }
    }

    mImageView.setImageBitmapResetBase(croppedImage, true);
    mImageView.center(true, true);
    mImageView.mHighlightViews.clear();

    // Return the cropped image directly or save it to the specified URI.
    Bundle myExtras = getIntent().getExtras();
    if (myExtras != null
        && (myExtras.getParcelable("data") != null || myExtras.getBoolean("return-data"))) {
      Bundle extras = new Bundle();
      extras.putParcelable("data", croppedImage);
      setResult(RESULT_OK, (new Intent()).setAction("inline-data").putExtras(extras));
      finish();
    } else {
      final Bitmap b = croppedImage;
      final int msdId = mSetWallpaper ? R.string.wallpaper : R.string.savingImage;
      Util.startBackgroundJob(
          this,
          this,
          null,
          getResources().getString(msdId),
          new Runnable() {
            public void run() {
              saveOutput(b);
            }
          },
          mHandler);
    }
  }
Пример #18
0
  private void onSaveClicked() {
    if (!mNeedCrop) {
      Bitmap nocropBitmap = createNoCropBitmap();
      mImageView.clear();
      if (nocropBitmap != mBitmap) {
        mBitmap.recycle();
        mBitmap = null;
      }
      if (null != nocropBitmap) {
        // Return the cropped image directly or save it to the specified
        // URI.
        Bundle myExtras = getIntent().getExtras();
        if (myExtras != null
            && (myExtras.getParcelable("data") != null || myExtras.getBoolean("return-data"))) {
          Bundle extras = new Bundle();
          extras.putParcelable("data", nocropBitmap);
          setResult(
              RESULT_OK,
              (new Intent()).setAction(ICustomAction.ACTION_INLINE_DATA).putExtras(extras));
          finish();
        } else {
          final Bitmap b = nocropBitmap;
          final int msdId = mSetWallpaper ? R.string.wallpaper : R.string.savingImage;
          Util.startBackgroundJob(
              this,
              null,
              getResources().getString(msdId),
              new Runnable() {
                @Override
                public void run() {
                  saveOutput(b);
                }
              },
              mHandler);
        }
      } else {
        setResult(RESULT_CANCELED);
        finish();
      }
      return;
    }
    // TODO this code needs to change to use the decode/crop/encode single
    // step api so that we don't require that the whole (possibly large)
    // bitmap doesn't have to be read into memory
    if (mCrop == null) {
      return;
    }

    if (mSaving) {
      return;
    }
    mSaving = true;

    Bitmap croppedImage = null;
    Bitmap.Config bmpConfig = mHasApha ? Bitmap.Config.ARGB_8888 : Bitmap.Config.ARGB_8888;

    // If the output is required to a specific size, create an new image
    // with the cropped image in the center and the extra space filled.
    if (mOutputX != 0 && mOutputY != 0 && !mScale) {
      // Don't scale the image but instead fill it so it's the
      // required dimension
      try {
        croppedImage = Bitmap.createBitmap(mOutputX, mOutputY, bmpConfig);
      } catch (OutOfMemoryError e) {
        // 创建失败
        e.printStackTrace();
        OutOfMemoryHandler.handle();
        Toast.makeText(this, getString(R.string.err_out_of_memory), Toast.LENGTH_SHORT);
        // Release bitmap memory as soon as possible
        mImageView.clear();
        mBitmap.recycle();
        mBitmap = null;

        setResult(RESULT_CANCELED);
        finish();
        return;
      }

      Canvas canvas = new Canvas(croppedImage);
      Rect srcRect = mCrop.getCropRect();
      Rect dstRect = new Rect(0, 0, mOutputX, mOutputY);

      int dx = (srcRect.width() - dstRect.width()) / 2;
      int dy = (srcRect.height() - dstRect.height()) / 2;

      // If the srcRect is too big, use the center part of it.
      srcRect.inset(Math.max(0, dx), Math.max(0, dy));

      // If the dstRect is too big, use the center part of it.
      dstRect.inset(Math.max(0, -dx), Math.max(0, -dy));

      // Draw the cropped bitmap in the center
      canvas.drawBitmap(mBitmap, srcRect, dstRect, null);

      // Release bitmap memory as soon as possible
      mImageView.clear();
      mBitmap.recycle();
    } else {
      Rect r = mCrop.getCropRect();

      // int width = r.width();
      // int height = r.height();

      // If we are circle cropping, we want alpha channel, which is the
      // third param here.
      try {
        croppedImage = Bitmap.createBitmap(mOutputX, mOutputY, bmpConfig);
      } catch (OutOfMemoryError e) {
        e.printStackTrace();
        OutOfMemoryHandler.handle();
        // 创建失败
        // Toast.makeText(this, getString(R.string.err_out_of_memory),
        // Toast.LENGTH_SHORT).show();
        // Release bitmap memory as soon as possible
        mImageView.clear();
        mBitmap.recycle();

        setResult(RESULT_CANCELED);
        finish();
        return;
      }

      Canvas canvas = new Canvas(croppedImage);
      canvas.setDrawFilter(
          new PaintFlagsDrawFilter(
              0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG)); // 在有缩放的情况下需要提高绘图质量
      Rect dstRect = new Rect(0, 0, mOutputX, mOutputY);
      canvas.drawBitmap(mBitmap, r, dstRect, null);

      // Release bitmap memory as soon as possible
      mImageView.clear();
      mBitmap.recycle();

      // if (mCircleCrop) {
      // // OK, so what's all this about?
      // // Bitmaps are inherently rectangular but we want to return
      // // something that's basically a circle. So we fill in the
      // // area around the circle with alpha. Note the all important
      // // PortDuff.Mode.CLEAR.
      // Canvas c = new Canvas(croppedImage);
      // Path p = new Path();
      // p.addCircle(width / 2F, height / 2F, width / 2F,
      // Path.Direction.CW);
      // c.clipPath(p, Region.Op.DIFFERENCE);
      // c.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
      // }

      // If the required dimension is specified, scale the image.
      // if (mOutputX != 0 && mOutputY != 0 && mScale) {
      // croppedImage = Util.transform(new Matrix(), croppedImage,
      // mOutputX, mOutputY, mScaleUp, Util.RECYCLE_INPUT);
      // }
    }

    mImageView.setImageBitmapResetBase(croppedImage, true);
    mImageView.center(true, true);
    mImageView.mHighlightViews.clear();

    // Return the cropped image directly or save it to the specified URI.
    Bundle myExtras = getIntent().getExtras();
    if (myExtras != null
        && (myExtras.getParcelable("data") != null || myExtras.getBoolean("return-data"))) {
      Bundle extras = new Bundle();
      extras.putParcelable("data", croppedImage);
      setResult(
          RESULT_OK, (new Intent()).setAction(ICustomAction.ACTION_INLINE_DATA).putExtras(extras));
      finish();
    } else {
      final Bitmap b = croppedImage;
      final int msdId = mSetWallpaper ? R.string.wallpaper : R.string.savingImage;
      Util.startBackgroundJob(
          this,
          null,
          getResources().getString(msdId),
          new Runnable() {
            @Override
            public void run() {
              saveOutput(b);
            }
          },
          mHandler);
    }
  }
Пример #19
0
 /** 取消裁剪. */
 public void cropCancel() {
   mImageView.mHighlightViews.clear();
   mImageView.invalidate();
 }