Android 中实现选择图片生成缩略图点击查看大图的功能

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创建一个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创建一个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;
            }
        }
        // 激活系统图库,选择一张图片
        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;
            }
        }
        // 激活系统图库,选择一张图片
        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创建一个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);  // 小图不返回数据
        // 开启一个带有返回值的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 bmp = new ArrayList();

    public UploadPicGridAdapter(Context context,List 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);

        //绑定图片数据
        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



    

    

MyPagerAdapter .java
public class MyPagerAdapter extends PagerAdapter {
    private List list;

    public MyPagerAdapter(List 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 listViews = null;  //用于获取图片资源
    private int index = 0;   //获取当前点击的图片位置
    private MyPagerAdapter adapter;   //ViewPager的适配器
    private ArrayList 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();   //初始化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循环将试图添加到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);
                /**
                 * 图片的长按监听
                 * */
                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的改变监听
            //截取intent获取传递的值
            viewPager.setCurrentItem(position);    //viewpager显示指定的位置
        }
    }



    /**
     * pager的滑动监听
     * */
    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)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



    
    
    
    
    

    


大图容易引用OOM,引用了一个开源库

  compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0'

你可能感兴趣的:(Android 中实现选择图片生成缩略图点击查看大图的功能)