0、思路分析
基本思路:
就是通過選擇圖片勤揩,生成保存好2種圖片,一個(gè)是縮略圖秘蛔,一個(gè)是大圖陨亡,點(diǎn)擊相對(duì)應(yīng)的圖片,把大圖傳遞過去
1深员、工具類封裝
拍照或者獲取圖片的工具類:TakePhotoUtils
/**
* 拍照或者從相冊(cè)獲取照片负蠕、裁剪等操作工具類
*
* @author pangshulian
* @version 1.0
* @date 2016年9月9日 上午11:35:09
* 20180606 修改key值++100
*/
public class TakePhotoUtils {
/** 拍照 */
public static final int TAKE_PHOTO = 100;
/** 從相冊(cè)取 */
public static final int CHOOSE_PICTURE = 101;
/** 裁剪大圖 */
public static final int CROP_BIG_PICTURE = 102;
/** 裁剪小圖 */
public static final int CROP_SMALL_PICTURE = 103;
/** 壓縮的原圖 */
public static final int CROP_ORIGAL_PICTURE = 104;
private static final String FILE_CONTENT_FILEPROVIDER = "tecsun.jx.yt.phone.fileprovider";
private static TakePhotoUtils mInstance;
/** 存放照片uri */
public File mImageFile;
public TakePhotoUtils() {
// 設(shè)置圖片路徑
String _imageDir = "temp.jpg";
mImageFile = new File(Environment.getExternalStorageDirectory(), _imageDir);
}
public static TakePhotoUtils getInstance() {
if (mInstance == null) {
mInstance = new TakePhotoUtils();
}
return mInstance;
}
/**
* 通過uri生成Bitmap
*
* @param context
* @param uri
* @return
*/
public Bitmap decodeUriAsBitmap(Context context, Uri uri) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
return bitmap;
}
/**
* 拍照 TAKE_PHOTO
*/
public void takePhoto(Context context) {
takePhoto(context);
}
/**
* 拍照 TAKE_PHOTO
*/
public void takePhoto(Context context, int requestCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!PermissionsUtils.startRequestPermission((Activity) context, PermissionsUtils.CAMERA_PERMISSIONS, 1)) {
return;
}
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // "android.media.action.IMAGE_CAPTURE"
intent.addCategory("android.intent.category.DEFAULT");
//Android7.0以上URI
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//添加這一句表示對(duì)目標(biāo)應(yīng)用臨時(shí)授權(quán)該Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//通過FileProvider創(chuàng)建一個(gè)content類型的Uri
Uri uri = FileProvider.getUriForFile(context, FILE_CONTENT_FILEPROVIDER, mImageFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
} else {
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mImageFile));
}
((Activity) context).startActivityForResult(intent, requestCode);
}
/**
* 拍照
*/
public void takePhoto(Fragment fragment) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!PermissionsUtils.startRequestPermission(fragment.getActivity(), PermissionsUtils.CAMERA_PERMISSIONS, 1)) {
return;
}
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // "android.media.action.IMAGE_CAPTURE"
intent.addCategory("android.intent.category.DEFAULT");
//Android7.0以上URI
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//添加這一句表示對(duì)目標(biāo)應(yīng)用臨時(shí)授權(quán)該Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//通過FileProvider創(chuàng)建一個(gè)content類型的Uri
Uri uri = FileProvider.getUriForFile(fragment.getContext(), FILE_CONTENT_FILEPROVIDER, mImageFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
} else {
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mImageFile));
}
fragment.startActivityForResult(intent, TAKE_PHOTO);
}
/**
* 從相冊(cè)獲取
*/
public void pickPhoto(Context context, int requestCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!PermissionsUtils.startRequestPermission((Activity) context, PermissionsUtils.WRITE_EXTERNAL_STORAGE_PERMISSIONS, 1)) {
return;
}
}
// 激活系統(tǒng)圖庫,選擇一張圖片
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
// 開啟一個(gè)帶有返回值的Activity倦畅,請(qǐng)求碼為PHOTO_ZOOM
((Activity) context).startActivityForResult(intent, requestCode);
}
/**
* 從相冊(cè)獲取
*/
public void pickPhoto(Context context) {
pickPhoto( context, CHOOSE_PICTURE );
}
/**
* 從相冊(cè)獲取
*/
public void pickPhoto(Fragment fragment) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!PermissionsUtils.startRequestPermission(fragment.getActivity(),
PermissionsUtils.WRITE_EXTERNAL_STORAGE_PERMISSIONS, 1)) {
return;
}
}
// 激活系統(tǒng)圖庫遮糖,選擇一張圖片
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
// 開啟一個(gè)帶有返回值的Activity,請(qǐng)求碼為PHOTO_ZOOM
fragment.startActivityForResult(intent, CHOOSE_PICTURE);
}
/**
* 裁剪圖片滔迈,使用uri
* 默認(rèn)高寬比例1:1止吁,自定義高寬尺寸
*/
public void cropImageUri(Context context, Fragment fragment, Uri uri, int outputX, int outputY, int requestCode) {
Intent intent = setCropConfig(context, uri, outputX, outputY);
fragment.startActivityForResult(intent, requestCode);
}
/**
* 設(shè)置裁剪配置
*
* @param context
* @param uri
* @param outputX
* @param outputY
* @return
*/
private Intent setCropConfig(Context context, Uri uri, int outputX, int outputY) {
Uri imageUri;
Uri outputUri = null;
Intent intent = new Intent("com.android.camera.action.CROP");
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
String url = PhotoUtils.getPath(context, uri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
//添加這一句表示對(duì)目標(biāo)應(yīng)用臨時(shí)授權(quán)該Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//通過FileProvider創(chuàng)建一個(gè)content類型的Uri
imageUri = FileProvider.getUriForFile(context, FILE_CONTENT_FILEPROVIDER, new File(url));
outputUri = Uri.fromFile(mImageFile);
//TODO:outputUri不需要ContentUri,否則失敗
//outputUri = FileProvider.getUriForFile(activity, "com.solux.furniture.fileprovider", new File(crop_image));
} else
{
imageUri = uri;
outputUri = Uri.fromFile(mImageFile);
}
intent.setDataAndType(imageUri, "image/*");
} else {
intent.setDataAndType(uri, "image/*");
outputUri = Uri.fromFile(mImageFile);
}
// intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
// 裁剪框的比例,1:1
intent.putExtra("aspectX", 4);
intent.putExtra("aspectY", 5);
// 裁剪后輸出圖片的尺寸大小
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("scale", true);
// 切圖大小不足輸出燎悍,無黑框
intent.putExtra("scaleUpIfNeeded", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
intent.putExtra("return-data", false);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true); // no face detection
return intent;
}
/**
* 裁剪圖片敬惦,使用uri
* 默認(rèn)高寬比例1:1,自定義高寬尺寸
*/
public void cropImageUri(Context context, Uri uri, int outputX, int outputY, int requestCode) {
Intent intent = setCropConfig(context, uri, outputX, outputY);
((Activity) context).startActivityForResult(intent, requestCode);
}
/**
* 從相冊(cè)獲取后裁剪小圖谈山,不使用uri
* 默認(rèn)比例1:1俄删,自定義高寬尺寸
*/
public void cropSmallPicture(Context context, int outputX, int outputY) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
intent.putExtra("crop", "true");
// 裁剪框的比例,1:1
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// 裁剪后輸出圖片的尺寸大小
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("scale", true);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());// 圖片格式
intent.putExtra("noFaceDetection", true);// 取消人臉識(shí)別
intent.putExtra("return-data", true); // 小圖不返回?cái)?shù)據(jù)
// 開啟一個(gè)帶有返回值的Activity奏路,請(qǐng)求碼為CROP_SMALL_PICTURE
((Activity) context).startActivityForResult(intent, CROP_SMALL_PICTURE);
}
}
2畴椰、選擇圖片生成縮略圖頁面
UploadPicGridAdapter
/**
* Created by Administrator on 2018/7/27.
*/
public class UploadPicGridAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater inflater; // 視圖容器
public static List<Bitmap> bmp = new ArrayList<Bitmap>();
public UploadPicGridAdapter(Context context,List<Bitmap> bmp) {
inflater = LayoutInflater.from(context);
mContext = context;
this.bmp = bmp;
}
public int getCount() {
return (bmp.size() + 1);
}
public Object getItem(int arg0) {
return null;
}
public long getItemId(int arg0) {
return 0;
}
public void update(){
}
/**
* ListView Item設(shè)置
*/
public View getView(final int position, View convertView, ViewGroup parent) {
final int coord = position;
UploadPicGridAdapter.ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_published_grida, parent, false);
holder = new UploadPicGridAdapter.ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.iv_item);
holder.iv_del = (ImageView) convertView.findViewById(R.id.iiv_del);
convertView.setTag(holder);
} else {
holder = (UploadPicGridAdapter.ViewHolder) convertView.getTag();
}
if (position == bmp.size()) {
holder.image.setImageBitmap(BitmapFactory.decodeResource(mContext.getResources(),
R.drawable.icon_addpic_upload));
holder.iv_del.setVisibility(View.GONE);
if (position == 3)
{
holder.image.setVisibility(View.GONE);
}
} else {
holder.image.setImageBitmap(bmp.get(position));
holder.iv_del.setVisibility(View.VISIBLE);
holder.iv_del.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mOnDelItemPhotoClickListener != null){
mOnDelItemPhotoClickListener.onDelItemPhotoClick(position);
}
}
});
}
return convertView;
}
public interface OnDelItemPhotoClickListener{
void onDelItemPhotoClick(int position);
}
public OnDelItemPhotoClickListener mOnDelItemPhotoClickListener;
public void setOnDelItemPhotoClickListener(OnDelItemPhotoClickListener mOnDelItemPhotoClickListener){
this.mOnDelItemPhotoClickListener = mOnDelItemPhotoClickListener;
}
public class ViewHolder {
public ImageView image;
public ImageView iv_del;
}
}
主邏輯核心代碼
//綁定點(diǎn)擊事件
mGvPhoto.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
//判斷點(diǎn)擊的是否是圖片
if (arg2 == bmp.size()) {
//顯示選擇提示窗
TakePhotoUtils.getInstance().pickPhoto(context);
} else {
//進(jìn)入圖片預(yù)覽頁面
EventBus.getDefault().postSticky(new EventMessage(1,origalBmp));
Intent intent = new Intent(context, ShowImageActivity.class);
intent.putExtra("id", arg2); //將當(dāng)前點(diǎn)擊的位置傳遞過去
context.startActivity(intent); //啟動(dòng)Activity
}
}
});
adapter.setOnDelItemPhotoClickListener(new UploadPicGridAdapter.OnDelItemPhotoClickListener() {
@Override
public void onDelItemPhotoClick(int position) {
if (bmp != null && bmp.size() > 0){
bmp.remove(position);
adapter.notifyDataSetChanged();
}
if (origalBmp != null && origalBmp.size() > 0){
origalBmp.remove(position);
}
}
});
......
@Override
public void onActivityResult(int pRequestCode, int pResultCode, Intent pData) {
Uri uri;
if (pResultCode == Activity.RESULT_OK) {
switch (pRequestCode) {
// 從相冊(cè)取
case TakePhotoUtils.CHOOSE_PICTURE:
origalUri = pData.getData();
file = BitmapUtils.getFileFromMediaUri(context, origalUri);
newFile = CompressHelper.getDefault(getApplicationContext()).compressToFile(file);
Bitmap photoBmp = null;
try {
// photoBmp = BitmapUtils.getBitmapFormUri(UserFeedbackActivity.this, Uri.fromFile(file));
photoBmp = BitmapFactory.decodeFile(newFile.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
int degree = BitmapUtils.getBitmapDegree(newFile.getAbsolutePath());
/**
* 把圖片旋轉(zhuǎn)為正的方向
*/
Bitmap newbitmap = BitmapUtils.rotateBitmapByDegree(photoBmp, degree);
origalBmp.add(newbitmap);
zoomImage(newbitmap,width,width);
// TakePhotoUtils.getInstance().cropImageUri(context, origalUri, width, width, TakePhotoUtils.CROP_BIG_PICTURE);
break;
case TakePhotoUtils.CROP_BIG_PICTURE:
// 剪大圖用uri
if (TakePhotoUtils.getInstance().mImageFile != null) {
Bitmap bitmap = TakePhotoUtils.getInstance().decodeUriAsBitmap(context, Uri.fromFile
(TakePhotoUtils.getInstance().mImageFile));
Bitmap image = ImageFactory.ratio(bitmap, width, width);
if (image != null) {
// spath:生成圖片取個(gè)名字和路徑包含類型
String fileName = "image" + System.currentTimeMillis()
+ ".png";
String outPath = context.getFilesDir().getAbsolutePath() + fileName;
try {
ImageFactory.compressAndGenImage(image, outPath, 140);
} catch (IOException e) {
e.printStackTrace();
}
File file = new File(outPath);
bmp.add(image);
adapter.notifyDataSetChanged();
}
}
break;
}
}
super.onActivityResult(pRequestCode, pResultCode, pData);
}
/**
* 縮放圖片
* @param bitmap
* @param width
* @param height
*/
private void zoomImage(Bitmap bitmap,int width,int height){
zoomImageBitmap = BitmapUtils.zoomImage(bitmap, width, height);
bmp.add(zoomImageBitmap);
adapter.notifyDataSetChanged();
}
/**
* 讓圖片按照屏幕3等分
*/
public void Init() {
//初始化控件
mGvPhoto = (GridView) findViewById(R.id.gv_photo);
//設(shè)置gridview分割線為透明
mGvPhoto.setSelector(new ColorDrawable(Color.TRANSPARENT));
//初始化適配器
adapter = new UploadPicGridAdapter(UserFeedbackActivity.this,bmp);
//綁定圖片數(shù)據(jù)
mGvPhoto.setAdapter(adapter);
int screenWidth = WindowManagerUtils.getScreenWidth(context);
width = screenWidth/3;
}
@Override
protected void onDestroy() {
super.onDestroy();
if (zoomImageBitmap != null && !zoomImageBitmap.isRecycled()){
zoomImageBitmap.recycle();
}
}
3、ShowImageActivity 大圖片展示頁面
show_image_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/show_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
MyPagerAdapter .java
public class MyPagerAdapter extends PagerAdapter {
private List<View> list;
public MyPagerAdapter(List<View> list) {
this.list = list;
}
@Override
public int getCount() {
if (list != null && list.size() > 0) {
return list.size();
} else {
return 0;
}
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
container.addView(list.get(position));
return list.get(position);
}
//
// @Override
// public int getItemPosition(Object object) {
// return POSITION_NONE;
// }
}
ShowImageActivity .java
public class ShowImageActivity extends AppCompatActivity {
private ViewPager viewPager; //聲明viewpage
private List<View> listViews = null; //用于獲取圖片資源
private int index = 0; //獲取當(dāng)前點(diǎn)擊的圖片位置
private MyPagerAdapter adapter; //ViewPager的適配器
private ArrayList<Bitmap> bmp = null;
private int position;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); //去除標(biāo)題欄
setContentView(R.layout.show_image_layout); //綁定布局
inigView();
initData();
}
private void inigView() {
viewPager = (ViewPager) findViewById(R.id.show_view_pager); //綁定viewpager的id
}
private void initData() {
listViews = new ArrayList<View>(); //初始化list
position = getIntent().getIntExtra("id",0);
LogUtils.d("position====================="+position);
}
private void inint() {
if (bmp != null && bmp.size() > 0){
for (int i = 0; i < bmp.size(); i++) { //for循環(huán)將試圖添加到list中
View view = LayoutInflater.from(getApplicationContext()).inflate(
R.layout.view_pager_item, null); //綁定viewpager的item布局文件
// ImageView iv = (ImageView) view.findViewById(R.id.view_image); //綁定布局中的id
// iv.setImageBitmap(bmp.get(i)); //設(shè)置當(dāng)前點(diǎn)擊的圖片
SubsamplingScaleImageView iv = (SubsamplingScaleImageView) view.findViewById(R.id.view_image); //綁定布局中的id
iv.setImage(ImageSource.bitmap(bmp.get(i)));
listViews.add(view);
/**
* 圖片的長按監(jiān)聽
* */
iv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
//彈出提示斜脂,提示內(nèi)容為當(dāng)前的圖片位置
Toast.makeText(ShowImageActivity.this, "這是第" + (index + 1) + "圖片", Toast.LENGTH_SHORT).show();
return false;
}
});
}
adapter = new MyPagerAdapter(listViews);
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new PageChangeListener()); //設(shè)置viewpager的改變監(jiān)聽
//截取intent獲取傳遞的值
viewPager.setCurrentItem(position); //viewpager顯示指定的位置
}
}
/**
* pager的滑動(dòng)監(jiān)聽
* */
private class PageChangeListener implements OnPageChangeListener {
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageSelected(int arg0) {
index = arg0;
}
}
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
public void onEventMainThread(EventMessage em) {
LogUtils.d("onEventMainThread=====================");
bmp = (ArrayList<Bitmap>)em.obj;
LogUtils.d("bmp====================="+bmp.size());
int byteCount = bmp.get(0).getByteCount();
LogUtils.d("byteCount====================="+byteCount);
inint(); //初始化
}
@Override
protected void onResume() {
super.onResume();
if (!EventBus.getDefault().isRegistered(this)){
LogUtils.d("EventBus.getDefault().register=====================");
EventBus.getDefault().register(this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
view_pager_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black">
<!--<ImageView-->
<!--android:layout_centerInParent="true"-->
<!--android:id="@+id/view_image"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--/>-->
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
android:layout_centerInParent="true"
android:id="@+id/view_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
大圖容易引用OOM,引用了一個(gè)開源庫
compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0'