Android开发——相册拍照_02.将拍照得到或相册中选择的图片显示在ImageView中

继续之前所讲
同时打开相册或拍照完成后,就可以选择图片或拍照,然后目的是将所得图片显示在ImageView控件中

之前写的工具类里调用了startActivityForResult方法,于是在需要重写onActivityResult方法

在写此方法之前,首先需要注意的两点:
1.如果是从相册中选择的图片,那么会得到一个图片的Uri,而且在Android系统4.4以上的图片通过Uri得到的path为虚假的,并不是真实的地址,所以要写一个工具类,将Uri转换为String类型的path路径。
2.为了应用的流畅性和内存优化,需要将得到的图片进行缩放,然后将缩放之后的图片显示在ImageView控件上。

于是先将准备工作做好

1:将Uri转换为Path(4.4以上)

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class GetRealPathFromUri
{
    /**
     * 根据Uri获取图片绝对路径,解决Android4.4以上版本Uri转换
     * 
     * @param activity
     * @param imageUri
     * @author yaoxing
     * @date 2014-10-12
     */
    @TargetApi(19)
    public static String getImageAbsolutePath(Activity context, Uri imageUri)
    {
        if (context == null || imageUri == null)
            return null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT
                && DocumentsContract.isDocumentUri(context, imageUri))
        {
            if (isExternalStorageDocument(imageUri))
            {
                String docId = DocumentsContract.getDocumentId(imageUri);
                String[] split = docId.split(":");
                String type = split[0];
                if ("primary".equalsIgnoreCase(type))
                {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            } else if (isDownloadsDocument(imageUri))
            {
                String id = DocumentsContract.getDocumentId(imageUri);
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
                        Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            } else if (isMediaDocument(imageUri))
            {
                String docId = DocumentsContract.getDocumentId(imageUri);
                String[] split = docId.split(":");
                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;
                }
                String selection = MediaStore.Images.Media._ID + "=?";
                String[] selectionArgs = new String[]
                {
                        split[1]
                };
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        } // MediaStore (and general)
        else if ("content".equalsIgnoreCase(imageUri.getScheme()))
        {
            // Return the remote address
            if (isGooglePhotosUri(imageUri))
                return imageUri.getLastPathSegment();
            return getDataColumn(context, imageUri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(imageUri.getScheme()))
        {
            return imageUri.getPath();
        }
        return null;
    }

    public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs)
    {
        Cursor cursor = null;
        String column = MediaStore.Images.Media.DATA;
        String[] projection =
        {
                column
        };
        try
        {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst())
            {
                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());
    }

}

这个工具类是在网络中找到的大神所写,拿来就用Orz

2:将得到 图片根据ImageView控件大小来进行缩放,得到缩放值

/**
     * 动态获取图片的缩放值
     * @param options  BitmapFactory.Options
     * @param reqWidth 设定的Img控件宽度
     * @param reqHeight 设定的Img控件高度
     * @return inSampleSize
     */
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
    {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth)
        {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
            {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

这个方法最好也写在工具类里

这样,准备工作就完成了,接下来就需要将图片显示出来了

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK)
        {
            String path = null;
            Options opts = new Options();
            if (requestCode == 1)
            {
                // 如果是相机拍照,那么得到的data会为空,所以添加判断
                if (data != null)
                {
                    Uri address = data.getData();
                    // 将得到的Uri转换为真实的path路径
                    path = GetRealPathFromUri.getImageAbsolutePath(ApplyCourierActivity.this, address);
                } else
                {
                    path = Environment.getExternalStorageDirectory().getAbsolutePath()
                            + "/DJGXpic/applycourier_true.png";
                }
                // 为了内存考虑,需要将得到的图片根据ImageView的控件大小来进行缩放,然后再显示到ImageView上
                // inJustDecodeBounds方法为true时,得到bitmap时不分配内存
                opts.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(path, opts);
                // 根据options来获得inSampleSize缩放值
                int inSampleSize = ChooseImageUtils.calculateInSampleSize(opts, dpTopx(70), dpTopx(100));
                opts.inSampleSize = inSampleSize;
                // 然后再根据options的缩放值将显示出来的图片进行缩放,并进行内存分配
                opts.inJustDecodeBounds = false;
                Bitmap bitmap = BitmapFactory.decodeFile(path, opts);
                img.setImageBitmap(bitmap);
        }
    }

上面代码中的dpTopx是将dp值转换为px,因为在获得图片缩放值的方法里,系统默认是用PX为单位的,而我设定的ImageView控件宽高为70dp*100dp

/**
     * 获取手机屏幕密度,将dp值转换为px
     * 
     * @param dpValue
     * @param activity
     * @return px
     */
    private int dpTopx(float dpValue)
    {
        // 获取手机屏幕密度
        final float scale = getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

这样就实现了将得到的图片显示出来的功能

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值