使用xutils在线预览和压缩保存图片

本文介绍如何使用XUtils库实现图片的在线预览、比例压缩及质量压缩,并提供了保存压缩图片到指定路径的方法。

学习网址:
xutils按照图片的比例压缩接口 - zhiqiang_zhao - 优快云博客 http://m.blog.youkuaiyun.com/weixin_38501485/article/details/74529799

xutils还可以通过get方法直接下载图片文件,得到的是一个File对象,同时还可自行指定保存位置,详见使用xutils在线预览和下载图片

我按各个部分实现的功能把代码分开,所有部分合起来就是使用xutils在线预览和压缩保存图片。

在线预览图片

 /**
     * 下载并压缩图片:
     *  x.image().loadDrawable()方法并不会保存图片,只是可以显示出来而已,即在线预览功能;
     *  但通过此方法可以获取到图片对象,然后进行比例、质量压缩,
     *  然后再把压缩后的图片保存到本地保存到本地。
     */
    public void downloadAndZipImage() {
        ImageOptions imageOptions = new ImageOptions.Builder()
//                    .setSize(DensityUtil.dip2px(120), DensityUtil.dip2px(120))
//                    .setRadius(DensityUtil.dip2px(5))
                // 如果ImageView的大小不是定义为wrap_content, 不要crop.设置成fasle就好了
//                    .setCrop(false) // 很多时候设置了合适的scaleType也不需要它.
                // 加载中或错误图片的ScaleType
                //.setPlaceholderScaleType(ImageView.ScaleType.MATRIX)
//                    .setImageScaleType(ImageView.ScaleType.FIT_XY)
                .setLoadingDrawableId(R.mipmap.ic_launcher)//加载中的图片
                .setFailureDrawableId(R.mipmap.ic_launcher)//默认的图片
                .build();
        x.image().loadDrawable(imgUrl, imageOptions, new Callback.CommonCallback<Drawable>() {
            @Override
            public void onSuccess(Drawable result) {
                BitmapDrawable bd = (BitmapDrawable) result;
//                Bitmap bitmap = bd.getBitmap();
//                img.setImageBitmap(bitmap);//只是显示在界面上但并没有保存图片
                mBitmap = proportionCompressImage(bd.getBitmap());
                img.setImageBitmap(mBitmap);

                SimpleDateFormat time = new SimpleDateFormat("yyyyMMddHHmmss");
                String fileName = "zip_" + time.format(System.currentTimeMillis());
                if(saveImageFile(mBitmap, fileDir.getAbsolutePath(), fileName + ".jpg")){
                    ToastUtil.showMessage("保存成功");
                }else {
                    ToastUtil.showMessage("保存失败");
                }
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                ex.printStackTrace();
            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {

            }
        });

    }

比例压缩图片

    /**
     * 比例压缩图片
     *
     * @param image
     * @return
     */
    private Bitmap proportionCompressImage(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        //判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
        if (baos.toByteArray().length / 1024 > 1024) {
            //重置baos即清空baos
            baos.reset();
            //这里压缩50%,把压缩后的数据存放到baos中
            image.compress(Bitmap.CompressFormat.JPEG, 50, baos);
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
        float hh = 800f;//这里设置高度为800f
        float ww = 480f;//这里设置宽度为480f
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0){
            be = 1;
        }
        newOpts.inSampleSize = be;//设置缩放比例
        newOpts.inPreferredConfig = Bitmap.Config.RGB_565;//降低图片从ARGB888到RGB565
        //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        return qualityCompressImage(bitmap);//压缩好比例大小后再进行质量压缩
    }

质量压缩图片

    /**
     * 质量压缩图片
     *
     * @param image
     * @return
     */
    private Bitmap qualityCompressImage(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        //质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        int options = 100;
        //循环判断如果压缩后图片是否大于100kb,大于继续压缩
        while (baos.toByteArray().length / 1024 > 100) {
            //重置baos即清空baos
            baos.reset();
            //每次都减少10
            options -= 10;
            //这里压缩options%,把压缩后的数据存放到baos中
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);
        }
        //把压缩后的数据baos存放到ByteArrayInputStream中
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        //把ByteArrayInputStream数据生成图片
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
        return bitmap;
    }

保存图片到指定路径

/**
     * 保存图片到指定路径
     * @param fileDirPath 文件夹绝对路径
     * @param fileName 图片名
     * @return
     */
    public boolean saveImageFile(Bitmap mBitmap,String fileDirPath, String fileName){
//        Bitmap mBitmap = BitmapFactory.decodeFile(fileDirPath + "/" + fileName);
        File currentFile = new File(fileDirPath,fileName);
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(currentFile);
            mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值