From 161a3ce346bcb79399e677ccf585c14a1279fe64 Mon Sep 17 00:00:00 2001 From: teach Date: Fri, 1 Nov 2019 15:38:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=89=AA=E8=A3=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96=EF=BC=8C=E8=AE=BE=E7=BD=AE=E5=9B=BE=E7=89=87=E5=89=AA?= =?UTF-8?q?=E8=A3=81=E5=AE=BD=E9=AB=98=E6=AF=94=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../imageselectdemo/MainActivity.java | 2 + .../imageselector/ClipImageActivity.java | 4 ++ .../imageselector/entry/RequestConfig.java | 4 ++ .../imageselector/utils/ImageSelector.java | 11 +++ .../imageselector/view/ClipImageView.java | 70 +++++++------------ 5 files changed, 48 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/com/donkingliang/imageselectdemo/MainActivity.java b/app/src/main/java/com/donkingliang/imageselectdemo/MainActivity.java index d994bf0..7d75f06 100644 --- a/app/src/main/java/com/donkingliang/imageselectdemo/MainActivity.java +++ b/app/src/main/java/com/donkingliang/imageselectdemo/MainActivity.java @@ -86,6 +86,7 @@ public void onClick(View v) { ImageSelector.builder() .useCamera(true) // 设置是否使用拍照 .setCrop(true) // 设置是否使用图片剪切功能。 + .setCropRatio(1.0f) // 图片剪切的宽高比,默认1.0f。宽固定为手机屏幕的宽。 .setSingle(true) //设置是否单选 .canPreview(true) //是否点击放大图片查看,,默认为true .start(this, REQUEST_CODE); // 打开相册 @@ -102,6 +103,7 @@ public void onClick(View v) { //拍照并剪裁 ImageSelector.builder() .setCrop(true) // 设置是否使用图片剪切功能。 + .setCropRatio(1.0f) // 图片剪切的宽高比,默认1.0f。宽固定为手机屏幕的宽。 .onlyTakePhoto(true) // 仅拍照,不打开相册 .start(this, REQUEST_CODE); break; diff --git a/imageselector/src/main/java/com/donkingliang/imageselector/ClipImageActivity.java b/imageselector/src/main/java/com/donkingliang/imageselector/ClipImageActivity.java index aa4886e..7f0fb1f 100644 --- a/imageselector/src/main/java/com/donkingliang/imageselector/ClipImageActivity.java +++ b/imageselector/src/main/java/com/donkingliang/imageselector/ClipImageActivity.java @@ -31,6 +31,7 @@ public class ClipImageActivity extends Activity { private ClipImageView imageView; private int mRequestCode; private boolean isCameraImage; + private float cropRatio; @Override protected void onCreate(Bundle savedInstanceState) { @@ -43,6 +44,7 @@ protected void onCreate(Bundle savedInstanceState) { mRequestCode = config.requestCode; config.isSingle = true; config.maxSelectCount = 0; + cropRatio = config.cropRatio; setStatusBarColor(); ImageSelectorActivity.openActivity(this, mRequestCode, config); initView(); @@ -79,6 +81,8 @@ public void onClick(View v) { finish(); } }); + + imageView.setRatio(cropRatio); } @Override diff --git a/imageselector/src/main/java/com/donkingliang/imageselector/entry/RequestConfig.java b/imageselector/src/main/java/com/donkingliang/imageselector/entry/RequestConfig.java index e3bc0b0..961a08c 100644 --- a/imageselector/src/main/java/com/donkingliang/imageselector/entry/RequestConfig.java +++ b/imageselector/src/main/java/com/donkingliang/imageselector/entry/RequestConfig.java @@ -19,8 +19,10 @@ public class RequestConfig implements Parcelable { public boolean canPreview = true; // 是否可以点击图片预览 public int maxSelectCount; //图片的最大选择数量,小于等于0时,不限数量,isSingle为false时才有用。 public ArrayList selected; //接收从外面传进来的已选择的图片列表。当用户原来已经有选择过图片,重新打开选择器,允许用户把先前选过的图片传进来,并把这些图片默认为选中状态。 + public float cropRatio = 1.0f; // 图片剪切的宽高比,宽固定为手机屏幕的宽。 public int requestCode; + @Override public int describeContents() { return 0; @@ -35,6 +37,7 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeByte(this.canPreview ? (byte) 1 : (byte) 0); dest.writeInt(this.maxSelectCount); dest.writeStringList(this.selected); + dest.writeFloat(this.cropRatio); dest.writeInt(this.requestCode); } @@ -49,6 +52,7 @@ protected RequestConfig(Parcel in) { this.canPreview = in.readByte() != 0; this.maxSelectCount = in.readInt(); this.selected = in.createStringArrayList(); + this.cropRatio = in.readFloat(); this.requestCode = in.readInt(); } diff --git a/imageselector/src/main/java/com/donkingliang/imageselector/utils/ImageSelector.java b/imageselector/src/main/java/com/donkingliang/imageselector/utils/ImageSelector.java index b10615e..03e44d4 100644 --- a/imageselector/src/main/java/com/donkingliang/imageselector/utils/ImageSelector.java +++ b/imageselector/src/main/java/com/donkingliang/imageselector/utils/ImageSelector.java @@ -64,6 +64,17 @@ public ImageSelectorBuilder setCrop(boolean isCrop) { return this; } + /** + * + * 图片剪切的宽高比,宽固定为手机屏幕的宽。 + * @param ratio + * @return + */ + public ImageSelectorBuilder setCropRatio(float ratio){ + config.cropRatio = ratio; + return this; + } + /** * 是否单选 * diff --git a/imageselector/src/main/java/com/donkingliang/imageselector/view/ClipImageView.java b/imageselector/src/main/java/com/donkingliang/imageselector/view/ClipImageView.java index 9f2d9d1..2c83c7d 100644 --- a/imageselector/src/main/java/com/donkingliang/imageselector/view/ClipImageView.java +++ b/imageselector/src/main/java/com/donkingliang/imageselector/view/ClipImageView.java @@ -19,7 +19,6 @@ import android.view.WindowManager; public class ClipImageView extends AppCompatImageView { - private PointF mDownPoint; private PointF mMiddlePoint; private Matrix mMatrix; @@ -46,6 +45,7 @@ public class ClipImageView extends AppCompatImageView { private float mCircleCenterX, mCircleCenterY; private float mCircleX, mCircleY; private boolean isCutImage; + private float mRatio = 1.0f; public ClipImageView(Context context) { super(context); @@ -95,23 +95,23 @@ public void run() { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); + setRadius(); + } + + private void setRadius() { + mTargetWidth = getScreenWidth(getContext()); + mTargetHeight = (int) (mTargetWidth * mRatio); mCircleCenterX = getWidth() / 2; mCircleCenterY = getHeight() / 2; mCircleX = mCircleCenterX - mTargetWidth / 2; mCircleY = mCircleCenterY - mTargetHeight / 2; } - private void setRadius() { - - int width = getScreenWidth(getContext()); - int height = getScreenHeight(getContext()); - - if (width > height) { - mTargetWidth = height; - mTargetHeight = height; - } else { - mTargetWidth = width; - mTargetHeight = width; + public void setRatio(float ratio) { + if (mRatio != ratio) { + mRatio = ratio; + setRadius(); + invalidate(); } } @@ -126,14 +126,17 @@ protected void onDraw(Canvas canvas) { rf = new RectF(r); } // 画入前景圆形蒙板层 - int sc = canvas.saveLayer(rf, null, Canvas.ALL_SAVE_FLAG); + int sc = canvas.saveLayer(rf, null, Canvas.ALL_SAVE_FLAG); //画入矩形黑色半透明蒙板层 canvas.drawRect(r, mFrontGroundPaint); //设置Xfermode,目的是为了去除矩形黑色半透明蒙板层和圆形的相交部分 mFrontGroundPaint.setXfermode(mXfermode); //画入正方形 - canvas.drawRect(mCircleCenterX - mTargetWidth / 2, mCircleCenterY - mTargetHeight / 2, - mCircleCenterX + mTargetWidth / 2, mCircleCenterY + mTargetHeight / 2, mFrontGroundPaint); + float left = mCircleCenterX - mTargetWidth / 2; + float top = mCircleCenterY - mTargetHeight / 2; + float right = mCircleCenterX + mTargetWidth / 2; + float bottom = mCircleCenterY + mTargetHeight / 2; + canvas.drawRect(left, top, right, bottom, mFrontGroundPaint); canvas.restoreToCount(sc); //清除Xfermode,防止影响下次画图 @@ -153,10 +156,11 @@ public Bitmap clipImage() { Bitmap targetBitmap = Bitmap.createBitmap(mTargetWidth, mTargetHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(targetBitmap); - RectF dst = new RectF(-bitmap.getWidth() / 2 + mTargetWidth / 2, -getHeight() - / 2 + mTargetHeight / 2, bitmap.getWidth() / 2 - + mTargetWidth / 2, getHeight() / 2 + mTargetHeight / 2); - + int left = -bitmap.getWidth() / 2 + mTargetWidth / 2; + int top = -getHeight() / 2 + mTargetHeight / 2; + int right = bitmap.getWidth() / 2 + mTargetWidth / 2; + int bottom = getHeight() / 2 + mTargetHeight / 2; + RectF dst = new RectF(left, top, right, bottom); canvas.drawBitmap(bitmap, null, dst, paint); setDrawingCacheEnabled(false); bitmap.recycle(); @@ -300,33 +304,12 @@ private void midPoint(PointF point, MotionEvent event) { * 横向、纵向居中 */ protected void center() { - float height = mBitmapHeight; float width = mBitmapWidth; - float screenWidth = getWidth(); - float screenHeight = getHeight(); - float scale = 1f; - if (width >= height) { - scale = screenWidth / width; - - if (scale * height < mTargetHeight) { - scale = mTargetHeight / height; - } - - } else { - if (height <= screenHeight) { - scale = screenWidth / width; - } else { - scale = screenHeight / height; - } + float scale = Math.max(mTargetWidth / width,mTargetHeight / height); - if (scale * width < mTargetWidth) { - scale = mTargetWidth / width; - } - } - - float deltaX = (screenWidth - width * scale) / 2f; - float deltaY = (screenHeight - height * scale) / 2f; + float deltaX = -(width * scale - getWidth()) / 2.0f; + float deltaY = -(height * scale - getHeight()) / 2.0f; mMatrix.postScale(scale, scale); mMatrix.postTranslate(deltaX, deltaY); setImageMatrix(mMatrix); @@ -351,4 +334,5 @@ public static int getScreenHeight(Context context) { wm.getDefaultDisplay().getMetrics(outMetrics); return outMetrics.heightPixels; } + }