Skip to content

Commit 27b9050

Browse files
author
teach
committed
图片剪裁优化,设置图片剪裁宽高比。
1 parent 202fdaa commit 27b9050

File tree

6 files changed

+52
-43
lines changed

6 files changed

+52
-43
lines changed

app/src/main/java/com/donkingliang/imageselectdemo/MainActivity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.content.Intent;
44
import android.os.Bundle;
5+
56
import androidx.appcompat.app.AppCompatActivity;
67
import androidx.recyclerview.widget.GridLayoutManager;
78
import androidx.recyclerview.widget.RecyclerView;
@@ -86,6 +87,7 @@ public void onClick(View v) {
8687
ImageSelector.builder()
8788
.useCamera(true) // 设置是否使用拍照
8889
.setCrop(true) // 设置是否使用图片剪切功能。
90+
.setCropRatio(1.0f) // 图片剪切的宽高比,默认1.0f。宽固定为手机屏幕的宽。
8991
.setSingle(true) //设置是否单选
9092
.canPreview(true) //是否点击放大图片查看,,默认为true
9193
.start(this, REQUEST_CODE); // 打开相册
@@ -102,6 +104,7 @@ public void onClick(View v) {
102104
//拍照并剪裁
103105
ImageSelector.builder()
104106
.setCrop(true) // 设置是否使用图片剪切功能。
107+
.setCropRatio(1.0f) // 图片剪切的宽高比,默认1.0f。宽固定为手机屏幕的宽。
105108
.onlyTakePhoto(true) // 仅拍照,不打开相册
106109
.start(this, REQUEST_CODE);
107110
break;

app/src/main/res/layout/adapter_image.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111
android:layout_height="wrap_content"
1212
android:layout_gravity="center"
1313
android:background="#010101"
14-
android:scaleType="centerCrop" />
14+
android:scaleType="centerInside" />
1515

1616
</FrameLayout>

imageselector/src/main/java/com/donkingliang/imageselector/ClipImageActivity.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class ClipImageActivity extends Activity {
3131
private ClipImageView imageView;
3232
private int mRequestCode;
3333
private boolean isCameraImage;
34+
private float cropRatio;
3435

3536
@Override
3637
protected void onCreate(Bundle savedInstanceState) {
@@ -43,6 +44,7 @@ protected void onCreate(Bundle savedInstanceState) {
4344
mRequestCode = config.requestCode;
4445
config.isSingle = true;
4546
config.maxSelectCount = 0;
47+
cropRatio = config.cropRatio;
4648
setStatusBarColor();
4749
ImageSelectorActivity.openActivity(this, mRequestCode, config);
4850
initView();
@@ -79,6 +81,8 @@ public void onClick(View v) {
7981
finish();
8082
}
8183
});
84+
85+
imageView.setRatio(cropRatio);
8286
}
8387

8488
@Override

imageselector/src/main/java/com/donkingliang/imageselector/entry/RequestConfig.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ public class RequestConfig implements Parcelable {
1919
public boolean canPreview = true; // 是否可以点击图片预览
2020
public int maxSelectCount; //图片的最大选择数量,小于等于0时,不限数量,isSingle为false时才有用。
2121
public ArrayList<String> selected; //接收从外面传进来的已选择的图片列表。当用户原来已经有选择过图片,重新打开选择器,允许用户把先前选过的图片传进来,并把这些图片默认为选中状态。
22+
public float cropRatio = 1.0f; // 图片剪切的宽高比,宽固定为手机屏幕的宽。
2223
public int requestCode;
2324

25+
2426
@Override
2527
public int describeContents() {
2628
return 0;
@@ -35,6 +37,7 @@ public void writeToParcel(Parcel dest, int flags) {
3537
dest.writeByte(this.canPreview ? (byte) 1 : (byte) 0);
3638
dest.writeInt(this.maxSelectCount);
3739
dest.writeStringList(this.selected);
40+
dest.writeFloat(this.cropRatio);
3841
dest.writeInt(this.requestCode);
3942
}
4043

@@ -49,6 +52,7 @@ protected RequestConfig(Parcel in) {
4952
this.canPreview = in.readByte() != 0;
5053
this.maxSelectCount = in.readInt();
5154
this.selected = in.createStringArrayList();
55+
this.cropRatio = in.readFloat();
5256
this.requestCode = in.readInt();
5357
}
5458

imageselector/src/main/java/com/donkingliang/imageselector/utils/ImageSelector.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,17 @@ public ImageSelectorBuilder setCrop(boolean isCrop) {
6464
return this;
6565
}
6666

67+
/**
68+
*
69+
* 图片剪切的宽高比,宽固定为手机屏幕的宽。
70+
* @param ratio
71+
* @return
72+
*/
73+
public ImageSelectorBuilder setCropRatio(float ratio){
74+
config.cropRatio = ratio;
75+
return this;
76+
}
77+
6778
/**
6879
* 是否单选
6980
*

imageselector/src/main/java/com/donkingliang/imageselector/view/ClipImageView.java

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212
import android.graphics.Rect;
1313
import android.graphics.RectF;
1414
import android.graphics.Xfermode;
15+
1516
import androidx.appcompat.widget.AppCompatImageView;
17+
1618
import android.util.AttributeSet;
1719
import android.util.DisplayMetrics;
20+
import android.util.Log;
1821
import android.view.MotionEvent;
1922
import android.view.WindowManager;
2023

@@ -46,6 +49,7 @@ public class ClipImageView extends AppCompatImageView {
4649
private float mCircleCenterX, mCircleCenterY;
4750
private float mCircleX, mCircleY;
4851
private boolean isCutImage;
52+
private float mRatio = 1.0f;
4953

5054
public ClipImageView(Context context) {
5155
super(context);
@@ -95,23 +99,23 @@ public void run() {
9599
@Override
96100
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
97101
super.onLayout(changed, left, top, right, bottom);
102+
setRadius();
103+
}
104+
105+
private void setRadius() {
106+
mTargetWidth = getScreenWidth(getContext());
107+
mTargetHeight = (int) (mTargetWidth * mRatio);
98108
mCircleCenterX = getWidth() / 2;
99109
mCircleCenterY = getHeight() / 2;
100110
mCircleX = mCircleCenterX - mTargetWidth / 2;
101111
mCircleY = mCircleCenterY - mTargetHeight / 2;
102112
}
103113

104-
private void setRadius() {
105-
106-
int width = getScreenWidth(getContext());
107-
int height = getScreenHeight(getContext());
108-
109-
if (width > height) {
110-
mTargetWidth = height;
111-
mTargetHeight = height;
112-
} else {
113-
mTargetWidth = width;
114-
mTargetHeight = width;
114+
public void setRatio(float ratio) {
115+
if (mRatio != ratio) {
116+
mRatio = ratio;
117+
setRadius();
118+
invalidate();
115119
}
116120
}
117121

@@ -126,14 +130,17 @@ protected void onDraw(Canvas canvas) {
126130
rf = new RectF(r);
127131
}
128132
// 画入前景圆形蒙板层
129-
int sc = canvas.saveLayer(rf, null, Canvas.ALL_SAVE_FLAG);
133+
int sc = canvas.saveLayer(rf, null, Canvas.ALL_SAVE_FLAG);
130134
//画入矩形黑色半透明蒙板层
131135
canvas.drawRect(r, mFrontGroundPaint);
132136
//设置Xfermode,目的是为了去除矩形黑色半透明蒙板层和圆形的相交部分
133137
mFrontGroundPaint.setXfermode(mXfermode);
134138
//画入正方形
135-
canvas.drawRect(mCircleCenterX - mTargetWidth / 2, mCircleCenterY - mTargetHeight / 2,
136-
mCircleCenterX + mTargetWidth / 2, mCircleCenterY + mTargetHeight / 2, mFrontGroundPaint);
139+
float left = mCircleCenterX - mTargetWidth / 2;
140+
float top = mCircleCenterY - mTargetHeight / 2;
141+
float right = mCircleCenterX + mTargetWidth / 2;
142+
float bottom = mCircleCenterY + mTargetHeight / 2;
143+
canvas.drawRect(left, top, right, bottom, mFrontGroundPaint);
137144

138145
canvas.restoreToCount(sc);
139146
//清除Xfermode,防止影响下次画图
@@ -153,10 +160,11 @@ public Bitmap clipImage() {
153160
Bitmap targetBitmap = Bitmap.createBitmap(mTargetWidth, mTargetHeight,
154161
Bitmap.Config.ARGB_8888);
155162
Canvas canvas = new Canvas(targetBitmap);
156-
RectF dst = new RectF(-bitmap.getWidth() / 2 + mTargetWidth / 2, -getHeight()
157-
/ 2 + mTargetHeight / 2, bitmap.getWidth() / 2
158-
+ mTargetWidth / 2, getHeight() / 2 + mTargetHeight / 2);
159-
163+
int left = -bitmap.getWidth() / 2 + mTargetWidth / 2;
164+
int top = -getHeight() / 2 + mTargetHeight / 2;
165+
int right = bitmap.getWidth() / 2 + mTargetWidth / 2;
166+
int bottom = getHeight() / 2 + mTargetHeight / 2;
167+
RectF dst = new RectF(left, top, right, bottom);
160168
canvas.drawBitmap(bitmap, null, dst, paint);
161169
setDrawingCacheEnabled(false);
162170
bitmap.recycle();
@@ -300,33 +308,12 @@ private void midPoint(PointF point, MotionEvent event) {
300308
* 横向、纵向居中
301309
*/
302310
protected void center() {
303-
304311
float height = mBitmapHeight;
305312
float width = mBitmapWidth;
306-
float screenWidth = getWidth();
307-
float screenHeight = getHeight();
308-
float scale = 1f;
309-
if (width >= height) {
310-
scale = screenWidth / width;
311-
312-
if (scale * height < mTargetHeight) {
313-
scale = mTargetHeight / height;
314-
}
315-
316-
} else {
317-
if (height <= screenHeight) {
318-
scale = screenWidth / width;
319-
} else {
320-
scale = screenHeight / height;
321-
}
322-
323-
if (scale * width < mTargetWidth) {
324-
scale = mTargetWidth / width;
325-
}
326-
}
313+
float scale = Math.max(mTargetWidth / width,mTargetHeight / height);
327314

328-
float deltaX = (screenWidth - width * scale) / 2f;
329-
float deltaY = (screenHeight - height * scale) / 2f;
315+
float deltaX = -(width * scale - getWidth()) / 2.0f;
316+
float deltaY = -(height * scale - getHeight()) / 2.0f;
330317
mMatrix.postScale(scale, scale);
331318
mMatrix.postTranslate(deltaX, deltaY);
332319
setImageMatrix(mMatrix);

0 commit comments

Comments
 (0)