android - Kotlin 图像压缩实现

标签 android firebase kotlin image-compression

我的旧实现以 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
        .....

    }
}

最佳答案

您似乎没有将任何内容传递到您的 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,用来显示选中的图片。

希望对你有帮助

关于android - Kotlin 图像压缩实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62898708/

相关文章:

java - 使用光标适配器选中复选框时,使用删除按钮删除 ListView 中的项目

javascript - 遍历 JSON 数组中的对象

java - 使用按钮在嵌套回收器 View 中动态添加子项

java - 新的 Firebase 通知替换现有的未读 Firebase 通知

android - 将 Firebase 数据导入 android 类

gradle - Flyway 和 gradle kotlin dsl

android - 检查 sdk 版本后缺少 PendingIntent 可变性标志给出警告

android - Kotlin 数据类的房间数据库错误

java - 在主要 Activity 中处理来自 dialogfragment 的按钮

c# - 如何更改 ListView 上所选项目的颜色?