Android压缩图片并且保存到本地内存卡中

24 篇文章 0 订阅

        亲爱的同学们,相信我们在软件开发中经常会遇到拍照,选择相册上传的功能。前几天遇到一个这样的一个问题。后台要求我上传的图片不能超过500KB,大家知道我们现在的智能手机像素越来越高,拍照的照片一般都是几兆甚至一二十兆。那么我们改怎么做呢,答案是一定的,那就是先进行压缩,然后在保存压缩后的图片上传。最近在网络上也搜索到了很多关于压缩的内容,相信大家会有和我同感,为什么都写的不清楚,或许我们可以实现我们的功能,但是这是如何实现的,为什么呢。下面我就贴出我的代码,每一步骤都会有详细的注释。希望会帮到大家。

    第一,就是压缩图片的方法。在我们选择照片或者拍照之后,将图片路径传入进去就可以进行压缩,然后返回我们一个Bitmap的对象。注释的比较清楚,哪里不明白的可以给我评论留言。

      

/**
     * @param path
     * @return
     * @throws IOException
     * 压缩图片
     */
    public static Bitmap revitionImageSize(String path) throws IOException {
        //根据文件路径,创建一个字节缓冲输入流
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(
                new File(path)));
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        //根据流返回一个位图也就是bitmap,当options.inJustDecodeBounds = true的时候不需要完全解码,
        // 它仅仅会把它的宽,高取回来给你,这样就不会占用太多的内存,也就不会那么频繁的发生OOM了
        BitmapFactory.decodeStream(in, null, options);
        //关闭流
        in.close();
        int i = 0;
        Bitmap bitmap = null;
        while (true) {
            // options.outWidth >> i 。右移运算符,num >> 1,相当于num除以2
            if ((options.outWidth >> i <= 1000) && (options.outHeight >> i <= 1000)) {
                //得到一个输入流
                in = new BufferedInputStream(new FileInputStream(new File(path)));
                //为了解决图片解码时候出现SanpleSize错误,设置恰当的inSampleSize可以使BitmapFactory分配更少的空间以消除该错误
                //你将 inSampleSize 赋值为2,那就是每隔2行采1行,每隔2列采一列,那你解析出的图片就是原图大小的1/4.
                // Math.pow(2.0D, i)次方运算,2的i次方是多少
                options.inSampleSize = (int) Math.pow(2.0D, i);
                // 这里之前设置为了true,所以要改为false,否则就创建不出图片
                options.inJustDecodeBounds = false;
                bitmap = BitmapFactory.decodeStream(in, null, options);
                break;
            }
            i += 1;
        }
        return bitmap;
    }
第二、当我们拿到这个Bitmap对象之后,我们就可以进行保存的操作,因为我们这个毕竟是个对象,我们通常的上传过程是需要上传的文件的。

    

 /**
     * @param bitmap
     * 保存图片到SD卡的方法
     */
    public void saveBitmapFile(Bitmap bitmap){
        //Environment.getExternalStorageDirectory() 获取Android外部存储的空间,当有外部SD卡就在外部SD卡上建立。
        //没有外部SD卡就在内部SD卡的非data/data/目录建立目录。(data/data/目录才是真正的内存目录。)
        //IMAGE_NAME文件的名字,随便起。比如(xxx.jpg)
        File tempFile = new File(Environment.getExternalStorageDirectory(), IMAGE_NAME );
        try {
            //创建一个输出流,将数据写入到创建的文件对象中。
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tempFile));
            30 是压缩率,表示压缩70%; 如果不压缩是100,
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
           /* 为什么要调用flush()方法?当FileOutputStream作为BufferedOutputStream构造函数的参数传入,然后对BufferedOutputStream进行写入操作,才能利用缓冲及flush()。
            查看BufferedOutputStream的源代码,发现所谓的buffer其实就是一个byte[]。
            BufferedOutputStream的每一次write其实是将内容写入byte[],当buffer容量到达上限时,会触发真正的磁盘写入。
            而另一种触发磁盘写入的办法就是调用flush()了。*/
            bos.flush();
            //关闭流对象
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } 
   最后告诉大家,可以先看看java中的文件流和字节流操作,以及Android的Bitmap对象,对理解上述的代码会很有帮助。希望能帮助到大家。共同进步,欢迎转载和留言。一起探讨。

关注微信公众号:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值