Android 压缩图片并写入文件(kotlin -- 附demo)

你好!

效果图

在这里插入图片描述

配置 & 动态权限

//动态权限
https://blog.csdn.net/chaseDreamer_/article/details/121077531?spm=1001.2014.3001.5501

选择图片

https://blog.csdn.net/chaseDreamer_/article/details/121035850?spm=1001.2014.3001.5501

压缩图片

private fun comImag(): Bitmap? {
	// chooseImagResult为上面选择图片选择后返回的图片数组
    var localMedia = chooseImagResult[0]
    var file = File(localMedia.realPath)

    var imgUri = file.toUri()
    //将图片转换为bitmap
    var bitmapImg = BitmapFactory.decodeStream(contentResolver.openInputStream(imgUri))

    val baos = ByteArrayOutputStream()
    bitmapImg.compress(Bitmap.CompressFormat.JPEG, 100, baos)
    if (baos.toByteArray().size / 1024 > 1024) { //判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
      baos.reset() //重置baos即清空baos
      bitmapImg.compress(Bitmap.CompressFormat.JPEG, 50, baos) //这里压缩50%,把压缩后的数据存放到baos中
    }
    var isBm: ByteArrayInputStream? = ByteArrayInputStream(baos.toByteArray())
    val newOpts = BitmapFactory.Options()
    //开始读入图片,此时把options.inJustDecodeBounds 设回true了
    newOpts.inJustDecodeBounds = true
    var bitmap = BitmapFactory.decodeStream(isBm, null, newOpts)
    newOpts.inJustDecodeBounds = false
    val w = newOpts.outWidth
    val h = newOpts.outHeight

    val hh = 800f //这里设置高度为800f
    val ww = 480f //这里设置宽度为480f
    //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
    var be = 1 //be=1表示不缩放
    if (w > h && w > ww) { //如果宽度大的话根据宽度固定大小缩放
      be = (newOpts.outWidth / ww).toInt()
    } else if (w < h && h > hh) { //如果高度高的话根据宽度固定大小缩放
      be = (newOpts.outHeight / hh).toInt()
    }
    if (be <= 0) be = 1
    newOpts.inSampleSize = be //设置缩放比例
    //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
    isBm = ByteArrayInputStream(baos.toByteArray())
    bitmap = BitmapFactory.decodeStream(isBm, null, newOpts)
    return compressImage(bitmap!!) //压缩好比例大小后再进行质量压缩
  }
 private fun compressImage(image: Bitmap): Bitmap? {
    val baos = ByteArrayOutputStream()
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos)
    var options = 90
    val length = baos.toByteArray().size / 1024
    if (length > 5000) {
      //重置baos即清空baos
      baos.reset()
      //质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
      image.compress(Bitmap.CompressFormat.JPEG, 10, baos)
    } else if (length > 4000) {
      baos.reset()
      image.compress(Bitmap.CompressFormat.JPEG, 20, baos)
    } else if (length > 3000) {
      baos.reset()
      image.compress(Bitmap.CompressFormat.JPEG, 50, baos)
    } else if (length > 2000) {
      baos.reset()
      image.compress(Bitmap.CompressFormat.JPEG, 70, baos)
    }
    //循环判断如果压缩后图片是否大于1M,大于继续压缩
    while (baos.toByteArray().size / 1024 > 1024) {
      //重置baos即清空baos
      baos.reset()
      //这里压缩options%,把压缩后的数据存放到baos中
      image.compress(Bitmap.CompressFormat.JPEG, options, baos)
      //每次都减少10
      options -= 10
    }
    //把压缩后的数据baos存放到ByteArrayInputStream中
    val isBm = ByteArrayInputStream(baos.toByteArray())
    //把ByteArrayInputStream数据生成图片
    return BitmapFactory.decodeStream(isBm, null, null)
  }

3.将返回的压缩完毕的bitmap写入手机

private fun writeInPhone(comBitmap: Bitmap?) {
    //获取路径
    var dir = Environment.getExternalStorageDirectory().absolutePath + "/"
    //获取内部存储状态
    val state = Environment.getExternalStorageState()
    //如果状态不是mounted,无法读写
    if (state != Environment.MEDIA_MOUNTED) {
      Toast.makeText(this, "图片存储失败~", Toast.LENGTH_SHORT).show()
      return
    }
    //通过Random()类生成数组命名
    val random = Random()
    val fileName2 = java.lang.String.valueOf(random.nextInt(Int.MAX_VALUE))
    val comFile = File(dir + fileName2.toString() + ".jpg")
    try {
      val out = FileOutputStream(comFile)
      comBitmap?.compress(Bitmap.CompressFormat.JPEG, 100, out)
      out.flush()
      out.close()
    } catch (e: Exception) {
      e.printStackTrace()
    }

    Glide.with(this).load(dir + fileName2.toString() + ".jpg").into(ci_ComImag)
    var fileSize = getFileSize(File(dir + fileName2.toString() + ".jpg"))
    text2.setText("压缩后:"+fileSize/1024+"kb")

  }

git出问题了,要demo联系我~

我是入梦,谢谢你的观看我的博客,觉着好用的话,麻烦帮忙点个赞呗,谢谢啦~ 如果有什么错误,请随时联系我噢~QQ:897589417

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值