(笔记)Android获取相册图片并返回

这篇博客介绍了如何在Android应用中从相册选择图片,并使用BitmapFactory进行按比例和质量压缩,以适应屏幕大小并控制文件大小。关键步骤包括启动相册选择,根据Uri获取Bitmap,以及使用自定义方法进行压缩。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//跳转至相册界面
protected void getImageFromAlbum() {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");//相片类型
        startActivityForResult(intent, PICK_PHOTO);
}

//返回接收图片,其中getBitmapFromUri()为根据Uri获取( 优化后的)图片
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_PHOTO) {
        Uri uri = data.getData();
        Bitmap bitmap = getBitmapFromUri(this, uri);
        ImageView iv = (ImageView) findViewById(R.id.iv_photo);
        iv.setImageBitmap(bitmap);
    }
}

//根据Uri获取图片,这个代码片格式
public static Bitmap getBitmapFromUri(Activity activity, Uri uri) {
        Bitmap bm = null;
        InputStream is = null;
        try {
            is = activity.getContentResolver().openInputStream(uri);
//            bm = BitmapFactory.decodeStream(is);
            bm = getBitmapFormUri(activity, uri);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bm;
    }

    //按屏幕压缩图片
    public static Bitmap getBitmapFormUri(Activity ac, Uri uri) throws FileNotFoundException, IOException {
        InputStream input = ac.getContentResolver().openInputStream(uri);
        BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
        onlyBoundsOptions.inJustDecodeBounds = true;
        onlyBoundsOptions.inDither = true;//optional
        onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional
        BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
        input.close();
        //获取图片宽高
        int imageWidth = onlyBoundsOptions.outWidth;
        int imageHeight = onlyBoundsOptions.outHeight;
        //获取屏幕宽高
        Display dp = ac.getWindowManager().getDefaultDisplay();
        int screenWidth = dp.getWidth();
        int screenHeight = dp.getHeight();
        int scale = 1;
        //设置缩放比例,哪个比例大,用哪个
        int scaleWidth = imageWidth / screenWidth;
        int scaleHeight = imageHeight / screenHeight;
        if (scaleWidth >= scaleHeight && scaleWidth > 0) {
            scale = scaleWidth;
        } else if (scaleWidth < scaleHeight) {
            scale = scaleHeight;
        }
        if (scale <= 0)
            scale = 1;
        //比例压缩
        BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
        bitmapOptions.inSampleSize = scale;//设置缩放比例
        bitmapOptions.inDither = true;//optional
        bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional
        //前一个输入流被读完了,重新建立输入流,否则读不出图片,这是个坑!
        input = ac.getContentResolver().openInputStream(uri);
        Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
        input.close();
        return compressImage(bitmap);//再进行质量压缩
    }

    //质量压缩方法
    public static Bitmap compressImage(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();//重置baos即清空baos
            //第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差  ,第三个参数:保存压缩后的数据的流
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
            options -= 10;//每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
        return bitmap;
}



注:
1、PICK_PHOTO是我自己定义的常量。
2、第三个方法是根据网上别人写的通过Uri获取图片,如果不想写,可以用Glide框架加载图片。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值