Skip to content

Commit eac0e07

Browse files
author
梁任彦
committed
添加图片单选剪裁功能。
1 parent 68ee698 commit eac0e07

File tree

8 files changed

+745
-9
lines changed

8 files changed

+745
-9
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,18 @@
1717
<category android:name="android.intent.category.LAUNCHER" />
1818
</intent-filter>
1919
</activity>
20-
<activity android:name="com.donkingliang.imageselector.ImageSelectorActivity"
21-
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
22-
android:configChanges="orientation|keyboardHidden|screenSize"/>
23-
<activity android:name="com.donkingliang.imageselector.PreviewActivity"
24-
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
25-
android:configChanges="orientation|keyboardHidden|screenSize"/>
20+
<activity
21+
android:name="com.donkingliang.imageselector.ImageSelectorActivity"
22+
android:configChanges="orientation|keyboardHidden|screenSize"
23+
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
24+
<activity
25+
android:name="com.donkingliang.imageselector.PreviewActivity"
26+
android:configChanges="orientation|keyboardHidden|screenSize"
27+
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
28+
<activity
29+
android:name="com.donkingliang.imageselector.ClipImageActivity"
30+
android:configChanges="orientation|keyboardHidden|screenSize"
31+
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
2632
</application>
2733

2834
</manifest>

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ protected void onCreate(Bundle savedInstanceState) {
3232
findViewById(R.id.btn_single).setOnClickListener(this);
3333
findViewById(R.id.btn_limit).setOnClickListener(this);
3434
findViewById(R.id.btn_unlimited).setOnClickListener(this);
35+
findViewById(R.id.btn_clip).setOnClickListener(this);
3536
}
3637

3738
@Override
@@ -62,6 +63,11 @@ public void onClick(View v) {
6263
//或者
6364
// ImageSelectorUtils.openPhoto(MainActivity.this, REQUEST_CODE, false, 0);
6465
break;
66+
67+
case R.id.btn_clip:
68+
//单选并剪裁
69+
ImageSelectorUtils.openPhotoAndClip(MainActivity.this, REQUEST_CODE);
70+
break;
6571
}
6672
}
6773
}

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,19 @@
2828
android:layout_below="@+id/btn_single"
2929
android:text="多选(不限数量)" />
3030

31+
<Button
32+
android:id="@+id/btn_clip"
33+
android:layout_width="wrap_content"
34+
android:layout_height="wrap_content"
35+
android:layout_alignTop="@+id/btn_unlimited"
36+
android:layout_marginLeft="10dp"
37+
android:layout_toRightOf="@+id/btn_unlimited"
38+
android:text="单选并剪裁" />
39+
3140
<android.support.v7.widget.RecyclerView
3241
android:id="@+id/rv_image"
33-
android:layout_marginTop="10dp"
34-
android:layout_below="@+id/btn_unlimited"
3542
android:layout_width="match_parent"
36-
android:layout_height="match_parent" />
43+
android:layout_height="match_parent"
44+
android:layout_below="@+id/btn_unlimited"
45+
android:layout_marginTop="10dp" />
3746
</RelativeLayout>
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package com.donkingliang.imageselector;
2+
3+
import android.app.Activity;
4+
import android.content.Intent;
5+
import android.content.pm.ActivityInfo;
6+
import android.graphics.Bitmap;
7+
import android.graphics.Color;
8+
import android.os.Build;
9+
import android.os.Bundle;
10+
import android.view.View;
11+
import android.view.Window;
12+
import android.view.WindowManager;
13+
import android.widget.FrameLayout;
14+
15+
import com.donkingliang.imageselector.utils.ImageSelectorUtils;
16+
import com.donkingliang.imageselector.utils.ImageUtil;
17+
import com.donkingliang.imageselector.utils.StringUtils;
18+
import com.donkingliang.imageselector.view.ClipImageView;
19+
20+
import java.io.File;
21+
import java.util.ArrayList;
22+
23+
public class ClipImageActivity extends Activity {
24+
25+
private FrameLayout btnConfirm;
26+
private FrameLayout btnBack;
27+
private ClipImageView imageView;
28+
private int mRequestCode;
29+
30+
@Override
31+
protected void onCreate(Bundle savedInstanceState) {
32+
super.onCreate(savedInstanceState);
33+
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
34+
setContentView(R.layout.activity_clip_image);
35+
36+
mRequestCode = getIntent().getIntExtra("requestCode", 0);
37+
38+
setStatusBarColor();
39+
ImageSelectorUtils.openPhoto(this, mRequestCode, true, 0);
40+
initView();
41+
}
42+
43+
/**
44+
* 修改状态栏颜色
45+
*/
46+
private void setStatusBarColor() {
47+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
48+
Window window = getWindow();
49+
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
50+
window.setStatusBarColor(Color.parseColor("#373c3d"));
51+
}
52+
}
53+
54+
private void initView() {
55+
imageView = (ClipImageView) findViewById(R.id.process_img);
56+
btnConfirm = (FrameLayout) findViewById(R.id.btn_confirm);
57+
btnBack = (FrameLayout) findViewById(R.id.btn_back);
58+
59+
btnConfirm.setOnClickListener(new View.OnClickListener() {
60+
@Override
61+
public void onClick(View v) {
62+
if (imageView.getDrawable() != null) {
63+
btnConfirm.setEnabled(false);
64+
confirm(imageView.clipImage());
65+
}
66+
}
67+
});
68+
btnBack.setOnClickListener(new View.OnClickListener() {
69+
@Override
70+
public void onClick(View v) {
71+
finish();
72+
}
73+
});
74+
}
75+
76+
@Override
77+
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
78+
super.onActivityResult(requestCode, resultCode, data);
79+
80+
if (data != null && requestCode == mRequestCode) {
81+
ArrayList<String> images = data.getStringArrayListExtra(ImageSelectorUtils.SELECT_RESULT);
82+
Bitmap bitmap = ImageUtil.decodeSampledBitmapFromFile(images.get(0), 720, 1080);
83+
if (bitmap != null) {
84+
imageView.setBitmapData(bitmap);
85+
} else {
86+
finish();
87+
}
88+
} else {
89+
finish();
90+
}
91+
}
92+
93+
private void confirm(Bitmap bitmap) {
94+
String imagePath = null;
95+
if (bitmap != null) {
96+
imagePath = ImageUtil.saveImage(bitmap, getCacheDir().getPath() + File.separator + "image_select");
97+
bitmap.recycle();
98+
bitmap = null;
99+
}
100+
101+
if (StringUtils.isNotEmptyString(imagePath)) {
102+
ArrayList<String> selectImages = new ArrayList<>();
103+
selectImages.add(imagePath);
104+
Intent intent = new Intent();
105+
intent.putStringArrayListExtra(ImageSelectorUtils.SELECT_RESULT, selectImages);
106+
setResult(RESULT_OK, intent);
107+
}
108+
finish();
109+
}
110+
111+
public static void openActivity(Activity context, int requestCode) {
112+
Intent intent = new Intent(context, ClipImageActivity.class);
113+
intent.putExtra("requestCode", requestCode);
114+
context.startActivityForResult(intent, requestCode);
115+
}
116+
}

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

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

33
import android.app.Activity;
44

5+
import com.donkingliang.imageselector.ClipImageActivity;
56
import com.donkingliang.imageselector.ImageSelectorActivity;
67

78
/**
@@ -34,4 +35,14 @@ public static void openPhoto(Activity activity, int requestCode,
3435
boolean isSingle, int maxSelectCount) {
3536
ImageSelectorActivity.openActivity(activity, requestCode, isSingle, maxSelectCount);
3637
}
38+
39+
/**
40+
* 打开相册,单选图片并剪裁。
41+
*
42+
* @param activity
43+
* @param requestCode
44+
*/
45+
public static void openPhotoAndClip(Activity activity, int requestCode) {
46+
ClipImageActivity.openActivity(activity, requestCode);
47+
}
3748
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package com.donkingliang.imageselector.utils;
2+
3+
import android.graphics.Bitmap;
4+
import android.graphics.BitmapFactory;
5+
import android.graphics.Matrix;
6+
import android.media.ExifInterface;
7+
import android.text.format.DateFormat;
8+
import android.util.Log;
9+
10+
import java.io.File;
11+
import java.io.FileNotFoundException;
12+
import java.io.FileOutputStream;
13+
import java.io.IOException;
14+
import java.util.Calendar;
15+
import java.util.Locale;
16+
17+
public class ImageUtil {
18+
19+
public static String saveImage(Bitmap bitmap, String path) {
20+
21+
String name = new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".png";
22+
FileOutputStream b = null;
23+
File file = new File(path);
24+
if (!file.exists()) {
25+
file.mkdirs();// 创建文件夹
26+
}
27+
28+
String fileName = path + File.separator + name;
29+
30+
try {
31+
b = new FileOutputStream(fileName);
32+
bitmap.compress(Bitmap.CompressFormat.JPEG, 75, b);// 把数据写入文件
33+
return fileName;
34+
} catch (FileNotFoundException e) {
35+
e.printStackTrace();
36+
} finally {
37+
try {
38+
if (b != null) {
39+
b.flush();
40+
b.close();
41+
}
42+
} catch (IOException e) {
43+
e.printStackTrace();
44+
}
45+
}
46+
return "";
47+
}
48+
49+
/**
50+
* 根据计算的inSampleSize,得到压缩后图片
51+
*
52+
* @param pathName
53+
* @param reqWidth
54+
* @param reqHeight
55+
* @return
56+
*/
57+
public static Bitmap decodeSampledBitmapFromFile(String pathName, int reqWidth, int reqHeight) {
58+
59+
int degree = 0;
60+
61+
try {
62+
ExifInterface exifInterface = new ExifInterface(pathName);
63+
int result = exifInterface.getAttributeInt(
64+
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
65+
switch (result) {
66+
case ExifInterface.ORIENTATION_ROTATE_90:
67+
degree = 90;
68+
break;
69+
case ExifInterface.ORIENTATION_ROTATE_180:
70+
degree = 180;
71+
break;
72+
case ExifInterface.ORIENTATION_ROTATE_270:
73+
degree = 270;
74+
break;
75+
}
76+
} catch (IOException e) {
77+
return null;
78+
}
79+
80+
try {
81+
82+
// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
83+
final BitmapFactory.Options options = new BitmapFactory.Options();
84+
options.inJustDecodeBounds = true;
85+
BitmapFactory.decodeFile(pathName, options);
86+
// 调用上面定义的方法计算inSampleSize值
87+
options.inSampleSize = calculateInSampleSize(options, reqWidth,
88+
reqHeight);
89+
90+
// 使用获取到的inSampleSize值再次解析图片
91+
options.inJustDecodeBounds = false;
92+
// options.inPreferredConfig = Bitmap.Config.RGB_565;
93+
Bitmap bitmap = BitmapFactory.decodeFile(pathName, options);
94+
95+
if (degree != 0) {
96+
Bitmap newBitmap = rotateImageView(bitmap, degree);
97+
bitmap.recycle();
98+
bitmap = null;
99+
return newBitmap;
100+
}
101+
102+
return bitmap;
103+
} catch (OutOfMemoryError error) {
104+
Log.e("eee", "内存泄露!");
105+
return null;
106+
}
107+
}
108+
109+
/**
110+
* 旋转图片
111+
*
112+
* @param bitmap
113+
* @param angle
114+
* @return Bitmap
115+
*/
116+
public static Bitmap rotateImageView(Bitmap bitmap, int angle) {
117+
//旋转图片 动作
118+
Matrix matrix = new Matrix();
119+
matrix.postRotate(angle);
120+
// 创建新的图片
121+
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
122+
}
123+
124+
/**
125+
* 计算inSampleSize,用于压缩图片
126+
*
127+
* @param options
128+
* @param reqWidth
129+
* @param reqHeight
130+
* @return
131+
*/
132+
private static int calculateInSampleSize(BitmapFactory.Options options,
133+
int reqWidth, int reqHeight) {
134+
// 源图片的宽度
135+
int width = options.outWidth;
136+
int height = options.outHeight;
137+
int inSampleSize = 1;
138+
139+
if (width > reqWidth && height > reqHeight) {
140+
// 计算出实际宽度和目标宽度的比率
141+
int widthRatio = Math.round((float) width / (float) reqWidth);
142+
int heightRatio = Math.round((float) height / (float) reqHeight);
143+
inSampleSize = Math.max(widthRatio, heightRatio);
144+
}
145+
146+
return inSampleSize;
147+
}
148+
149+
}

0 commit comments

Comments
 (0)