Android 中實現(xiàn)選擇圖片生成縮略圖點擊查看大圖的功能

GIF.gif

0、思路分析

image.png
image.png

基本思路:
就是通過選擇圖片,生成保存好2種圖片,一個是縮略圖,一個是大圖,點擊相對應的圖片,把大圖傳遞過去

1、工具類封裝

拍照或者獲取圖片的工具類:TakePhotoUtils

/**
 * 拍照或者從相冊獲取照片、裁剪等操作工具類
 *
 * @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;
    /** 從相冊取 */
    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() {
        // 設置圖片路徑
        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) {
            //添加這一句表示對目標應用臨時授權該Uri所代表的文件
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            //通過FileProvider創(chuàng)建一個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) {
            //添加這一句表示對目標應用臨時授權該Uri所代表的文件
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            //通過FileProvider創(chuàng)建一個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);
    }


    /**
     * 從相冊獲取
     */
    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/*");
        // 開啟一個帶有返回值的Activity,請求碼為PHOTO_ZOOM
        ((Activity) context).startActivityForResult(intent, requestCode);
    }

    /**
     * 從相冊獲取
     */
    public void pickPhoto(Context context) {
        pickPhoto( context, CHOOSE_PICTURE );
    }

    /**
     * 從相冊獲取
     */
    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/*");
        // 開啟一個帶有返回值的Activity,請求碼為PHOTO_ZOOM
        fragment.startActivityForResult(intent, CHOOSE_PICTURE);
    }

    /**
     * 裁剪圖片,使用uri
     * 默認高寬比例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);
    }

    /**
     * 設置裁剪配置
     *
     * @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)
            {
                //添加這一句表示對目標應用臨時授權該Uri所代表的文件
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                //通過FileProvider創(chuàng)建一個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
     * 默認高寬比例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);
    }

    /**
     * 從相冊獲取后裁剪小圖,不使用uri
     * 默認比例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);// 取消人臉識別
        intent.putExtra("return-data", true);  // 小圖不返回數(shù)據(jù)
        // 開啟一個帶有返回值的Activity,請求碼為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設置
     */
    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;
    }

}
主邏輯核心代碼
//綁定點擊事件
        mGvPhoto.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                //判斷點擊的是否是圖片
                if (arg2 == bmp.size()) {
                    //顯示選擇提示窗
                    TakePhotoUtils.getInstance().pickPhoto(context);
                } else {
                    //進入圖片預覽頁面
                    EventBus.getDefault().postSticky(new EventMessage(1,origalBmp));
                    Intent intent = new Intent(context, ShowImageActivity.class);
                    intent.putExtra("id", arg2);   //將當前點擊的位置傳遞過去
                    context.startActivity(intent);     //啟動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) {
                // 從相冊取
                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());

                    /**
                     * 把圖片旋轉為正的方向
                     */
                    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:生成圖片取個名字和路徑包含類型
                            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);
        //設置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;   //獲取當前點擊的圖片位置
    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);  //去除標題欄
        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));   //設置當前點擊的圖片

                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) {
                        //彈出提示,提示內容為當前的圖片位置
                        Toast.makeText(ShowImageActivity.this, "這是第" + (index + 1) + "圖片", Toast.LENGTH_SHORT).show();
                        return false;
                    }
                });
            }
            adapter = new MyPagerAdapter(listViews);
            viewPager.setAdapter(adapter);
            viewPager.setOnPageChangeListener(new PageChangeListener()); //設置viewpager的改變監(jiān)聽
            //截取intent獲取傳遞的值
            viewPager.setCurrentItem(position);    //viewpager顯示指定的位置
        }
    }



    /**
     * pager的滑動監(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,引用了一個開源庫

  compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0'
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容