首页 > 解决方案 > Kotlin 图像压缩实现

问题描述

我的旧实现以 JPEG 格式将图像上传到 Firebase 存储而不进行任何压缩

private fun sendToFirebase() {

        if (imgUri != null) {

            val fileRef = storageRef!!.child(username+ ".jpg")
    
            ....

            // code to upload and read image url
        }
    }

决定写一个图片压缩技术来压缩图片然后上传到Firebase Storage

结果:实现了图像压缩技术,见下文

新增压缩图片的代码

  1. 位图的 URI

    val bitmap = MediaStore.Images.Media.getBitmap(activity?.contentResolver, imgUri)
    
  2. 压缩Bitmap的方法

     private fun compressBitmap(bitmap: Bitmap, quality:Int):Bitmap{
        val stream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.WEBP, quality, stream)
        val byteArray = stream.toByteArray()
        return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
     }
    
  3. 位图压缩实现

     compressBitmap(bitmap, 80)
    

查询:如何将相同的压缩图像上传到 Firebase 存储

 private fun sendToFirebase() {

    if (imgUri != null) {

        // code to convert uri to bitmap <start>
        val bitmap = MediaStore.Images.Media.getBitmap(activity?.contentResolver, imgUri)

        compressBitmap(bitmap, 80)
        // code to convert uri to bitmap <end>


        // old implementation
        .....

    }
}

标签: androidfirebasekotlinimage-compression

解决方案


你似乎没有将任何东西传递给你的函数sendtoFirebase。我正在发布我为成功上传所做的代码。

你先看压缩,所以你需要这个;

private fun compressBitmap(bitmap: Bitmap, quality: Int): Bitmap {

    val stream = ByteArrayOutputStream()

    bitmap.compress(Bitmap.CompressFormat.WEBP,quality,stream)

    val byteArray = stream.toByteArray()

    arrayByte = byteArray

    
                uploadFile(arrayByte)
         
 
    return BitmapFactory.decodeByteArray(byteArray,0,byteArray.size)


}

在上面,uploadFile是对 firebase 上传的调用。我将压缩位图传递给函数。上传功能如下:

下面mImageURI是一个伴随对象,它是为压缩传递的 URI 的一部分。如果您不想进行检查,可以删除下面的 if 语句

 private fun uploadFile(data:ByteArray) {


    if (mImageUri != null){

        val storageref = imageref.child("put your image id here")

        storageref.putBytes(data).addOnSuccessListener {

                            Handler().postDelayed({

                                progressbar.setProgress(0)
                                Toast.makeText(activity, "Upload Successful", Toast.LENGTH_LONG).show()

                            }

                                , 1000)
               
        }.addOnFailureListener{e->

            Toast.makeText(activity,e.message,Toast.LENGTH_LONG).show()
        }.addOnProgressListener {taskSnapshot ->

            val progress = (100.0 * taskSnapshot.bytesTransferred/taskSnapshot.totalByteCount)

            progressbar.setProgress(progress.toInt())

        }

    }
    else if(mImageUri == null) {
        Toast.makeText(activity,"No File Selected",Toast.LENGTH_LONG).show()

    }
}

您不需要上面有进度条。如果文件很大,它只是一个很好的视觉效果,用户必须看到上传的进度。

你真的只需要确保你data进入.putbytes



编辑:对于您的 onActivity 结果,如果您的代码与我的代码相似,请使用;

覆盖乐趣 onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data)

    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK
        && data != null && data.getData() != null) {

            mImageUri = data.getData()!!

        image1.setImageURI(data.getData())


   }
}

上面的 image1 是当前页面上的一个 imageView,用来显示选中的图片。

希望这可以帮助


推荐阅读