• Android从相册获取图片


    应用中经常会有去相册获取图片的需求,每次总是会忘,现在这做个记录,以便以后查阅。

    从应用去相册获取图片主要有以下几个步骤:

    1、设置intent调用系统相册

    2、进入相册选取图片,如果相册没有满意的图片,可以使用相机照相获取,最后返回数据到应用

    3、应用获取图片后,调用裁剪程序对图片进行裁剪

    4、返回裁剪的图片并显示出来

    一、设置intent调用系统相册,并进入相册选取图片

    /**
     * 调用相册
     */
    private void goAlbums() {
            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            intent.setType("image/*");
            startActivityForResult(intent, SELECT_PIC);
     }

    通过以上设置进入相册,返回的图片数据交由Activity的onActivityResult方法处理,请求码是SELECT_PIC,请求码为int型,可以随意设置

    获取到返回的图片之后,下面便进入裁剪的步骤了

    二、调用裁剪程序对图片进行裁剪

    /**
         * 裁剪大图
         * @param context
         * @param uri
         */
        private void clipperBigPic(Context context, Uri uri) {
            if (null == uri) {
                return;
            }
            Intent intent = new Intent("com.android.camera.action.CROP");
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                String url = PhotoClipperUtil.getPath(context, uri);
                intent.setDataAndType(Uri.fromFile(new File(url)), "image/*");
            }
            //发送裁剪命令
            intent.putExtra("crop", true);
            //X方向上的比例
            intent.putExtra("aspectX", 1);
            //Y方向上的比例
            intent.putExtra("aspectY", 1);
            //裁剪区的宽
            intent.putExtra("outputX", 124);
            //裁剪区的高
            intent.putExtra("outputY", 124);
            //是否保留比例
            intent.putExtra("scale", true);
            //返回数据
            intent.putExtra("return-data", true);
            //输出图片格式
            intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
            //裁剪图片保存位置
            intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
            startActivityForResult(intent, SELECT_CLIPPER_PIC);
        }

    上面代码中的Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT,是因为KITKAT以上版本中返回的data数据和KITKAT以下版本的data数据可能不同,需要单独处理。

    下面的代码便是正常处理,设置裁剪的参数,请求的数据同样交由onActivityResult处理

    getTempUri为设置临时图片存储目录,代码如下:

    private Uri getTempUri() {
            return Uri.fromFile(getTempFile());
        }
    
        /**
         * 临时图片保存路径
         * @return
         */
        private File getTempFile() {
            File file = new File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME);
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return file;
        }

    上面代码中中的IMAGE_FILE_NAME需要自己指定

    上面代码中的PhotoClipperUtil类代码如下:

    package tmg.gotoalarm;
    
    import android.annotation.SuppressLint;
    import android.content.ContentUris;
    import android.content.Context;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Environment;
    import android.provider.DocumentsContract;
    import android.provider.MediaStore;
    
    public class PhotoClipperUtil {
    
        @SuppressLint("NewApi")
        public static String getPath(final Context context, final Uri uri) {
    
            final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    
            // DocumentProvider
            if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
                // ExternalStorageProvider
                if (isExternalStorageDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
    
                    if ("primary".equalsIgnoreCase(type)) {
                        return Environment.getExternalStorageDirectory() + "/" + split[1];
                    }
    
                }
                // DownloadsProvider
                else if (isDownloadsDocument(uri)) {
                    final String id = DocumentsContract.getDocumentId(uri);
                    final Uri contentUri = ContentUris.withAppendedId(
                            Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
    
                    return getDataColumn(context, contentUri, null, null);
                }
                // MediaProvider
                else if (isMediaDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
    
                    Uri contentUri = null;
                    if ("image".equals(type)) {
                        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    } else if ("video".equals(type)) {
                        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    } else if ("audio".equals(type)) {
                        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }
    
                    final String selection = "_id=?";
                    final String[] selectionArgs = new String[] {
                            split[1]
                    };
    
                    return getDataColumn(context, contentUri, selection, selectionArgs);
                }
            }
            // MediaStore (and general)
            else if ("content".equalsIgnoreCase(uri.getScheme())) {
                // Return the remote address
                if (isGooglePhotosUri(uri))
                    return uri.getLastPathSegment();
    
                return getDataColumn(context, uri, null, null);
            }
            // File
            else if ("file".equalsIgnoreCase(uri.getScheme())) {
                return uri.getPath();
            }
    
            return null;
        }
    
        /**
         * Get the value of the data column for this Uri. This is useful for
         * MediaStore Uris, and other file-based ContentProviders.
         *
         * @param context The context.
         * @param uri The Uri to query.
         * @param selection (Optional) Filter used in the query.
         * @param selectionArgs (Optional) Selection arguments used in the query.
         * @return The value of the _data column, which is typically a file path.
         */
        public static String getDataColumn(Context context, Uri uri, String selection,
                                           String[] selectionArgs) {
            Cursor cursor = null;
            final String column = "_data";
            final String[] projection = {
                    column
            };
    
            try {
                cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                        null);
                if (cursor != null && cursor.moveToFirst()) {
                    final int index = cursor.getColumnIndexOrThrow(column);
                    return cursor.getString(index);
                }
            } finally {
                if (cursor != null)
                    cursor.close();
            }
            return null;
        }
    
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is ExternalStorageProvider.
         */
        public static boolean isExternalStorageDocument(Uri uri) {
            return "com.android.externalstorage.documents".equals(uri.getAuthority());
        }
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is DownloadsProvider.
         */
        public static boolean isDownloadsDocument(Uri uri) {
            return "com.android.providers.downloads.documents".equals(uri.getAuthority());
        }
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is MediaProvider.
         */
        public static boolean isMediaDocument(Uri uri) {
            return "com.android.providers.media.documents".equals(uri.getAuthority());
        }
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is Google Photos.
         */
        public static boolean isGooglePhotosUri(Uri uri) {
            return "com.google.android.apps.photos.content".equals(uri.getAuthority());
        }
    }

    总的获取相册图片的流程如下:

    mGoAlarmIv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //调用系统相册,进入相册获取图片
                    goAlbums();
                }
            });    

    进入相册后,应用的中转工作交由onActivityResult处理

    @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (data == null) {
                return;
            }
            switch (requestCode) {
                case SELECT_PIC:
                   //获取图片后裁剪图片
                    clipperBigPic(this, data.getData());
                    break;
                case SELECT_CLIPPER_PIC:
                   //获取图片后保存图片到本地,是否需要保存看情况而定
                    saveBitmap(data);
                    //显示图片
                    showImage(mGoAlarmIv);
                    break;
            }
        }

    保存图片的代码如下:

    /**
         * 保存图片
         * @param data
         */
        private void saveBitmap(Intent data) {
            Bundle bundle = data.getExtras();
            if (bundle != null) {
                Bitmap bitmap = bundle.getParcelable("data");
                File file = new File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME);
                try {
                    file.createNewFile();
                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
                    fileOutputStream.flush();
                    fileOutputStream.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
            }
        }

    OK,以上便是第三方应用调用相册获取图片的整个流程。

  • 相关阅读:
    boot.asm
    C talk
    C 数据类型
    Locks, Deadlocks, and Synchronization
    C++的RTTI 观念和用途
    setup.asm
    驱动对象设备对象设备栈
    JNI 内存泄漏
    KMP 字符串匹配算法
    解开 Windows 下的临界区中的代码死锁
  • 原文地址:https://www.cnblogs.com/tyrion/p/4436993.html
Copyright © 2020-2023  润新知