android - Kotlin 图像压缩实现
问题描述
我的旧实现以 JPEG 格式将图像上传到 Firebase 存储而不进行任何压缩
private fun sendToFirebase() {
if (imgUri != null) {
val fileRef = storageRef!!.child(username+ ".jpg")
....
// code to upload and read image url
}
}
决定写一个图片压缩技术来压缩图片然后上传到Firebase Storage
结果:实现了图像压缩技术,见下文
新增压缩图片的代码
位图的 URI
val bitmap = MediaStore.Images.Media.getBitmap(activity?.contentResolver, imgUri)
压缩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) }
位图压缩实现
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,用来显示选中的图片。
希望这可以帮助
推荐阅读
- excel - 如何使用来自 WorksheetFunction.Unique() 的值填充数组?
- mysql - 创建配方数据库时,如何将 recipe_ID 与多个成分 ID 实例链接?
- c# - 将 DataRow 与其他 DataRow 进行比较
- pandas - 如何将 seaborn 的 catplot 绘制到 gridspec
- java - 扫描仪正在跳过一行并转到下一行
- r - 如何从匹配条件的行之后的行中返回一个值?
- r - R2jags :: JAGS“初始化模型”
- powershell - CmdletBinding 中的参数不是强制性的和错误/拼写错误检查
- java - 面向方面编程的异常处理
- java - 是否可以从序列化的 kryo 对象中提取单个字段值?