关于使用Glide加载图片,并保存

4 篇文章 0 订阅
1 篇文章 0 订阅

关于使用Glide加载图片,并保存

这是我的Github地址:https://github.com/brokes6
我的博客:https://brokes6.github.io/

本篇已Kotlin为主要语言

思路

  1. 首先通过Glide来加载图片
  2. 在RecyclerView中使用
    • 在外部,通过获取RecyclerView,在获取到ViewHodel,最后获取到Image
    • 将获取到Image通过“holder.itemView.imageView.drawable.toBitmap()”保存为Bitmap
    • 在通过requestContext.contextResolver的openOutputStream来存入本地图片文件夹

在RecyclerView中使用

  1. 如果使用了ViewPage,则先需要获取RecyclerView

    val holder = (binding.viewPager[0] as RecyclerView)
    

    通过调用viewpagep[0]来获取到RecyclerView

  2. 获取ViewHodel

    val holder = (binding.viewPager[0] as RecyclerView).findViewHolderForAdapterPosition(binding.viewPager.currentItem) as PhotoViewPagerHolder
    

    通过findViewHolderForAdapterPosition,传入Position 在转换为自己的ViewHodel即可

  3. 将Image转换为Bitmap

    val bitmap = holder.itemView.imageView.drawable.toBitmap()
    
  4. 如果API是否大于29

    • 大于29等于:由于大于等于29,所以就只能使用 requireContext().contentResolver.openOutputStream 来存储图片
    • 小于29:可以直接使用 MediaStore.Images.Media.insertImage 来保存
  5. 由于不管是否大于29,都可以使用 requireContext().contentResolver.openOutputStream 来保存图片,所以就讲这个了

  6. openOutputStream 接收2个参数(1.uri地址,2.mode模式(可无视))

  7. 创建一个空的 Image 保存 Uri

     val imageUrl = requireContext().contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    ContentValues())?: kotlin.run {
                    Toast.makeText(context, "存储失败", Toast.LENGTH_SHORT).show()
                }
    

    因为获取完的 Uri 是可为空的,所以需要写一个为空则干什么

    因为这个 Dome 是在 Fragment中,所以需要使用到 requestContext()

  8. 将图片保存到本地

      requireContext().contentResolver.openOutputStream(imageUrl as Uri).use {
                    if (bitmap.compress(Bitmap.CompressFormat.PNG,90,it)){
                        MainScope().launch { Toast.makeText(context, "存储成功", Toast.LENGTH_SHORT).show() }
                    }else{
                        MainScope().launch { Toast.makeText(context, "存储失败", Toast.LENGTH_SHORT).show() }
                    }
                }
    

    通过调用 Bitmap.compress() 来进行保存,我们可以根据 compress 的返回值来判断是否保存成功

    compress 接收3个参数:

    1. 保存格式
    2. 压缩程度(如果格式为JPEG,那么将无法压缩)
    3. 输出流

    Kotlin语法糖:use{} 它配合流使用在使用完流之后,自动关闭

  9. 由于保存图片本身是在主线程,如果遇到图片较大,那么可能会阻塞主线程,所以我们需要将他在子线程中运行

    private suspend fun saveImage() {
            withContext(Dispatchers.IO){
                val holder = (binding.viewPager[0] as RecyclerView).findViewHolderForAdapterPosition(binding.viewPager.currentItem) as PhotoViewPagerHolder
                val imageUrl = requireContext().contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    ContentValues())?: kotlin.run {
                    Toast.makeText(context, "存储失败", Toast.LENGTH_SHORT).show()
                }
                requireContext().contentResolver.openOutputStream(imageUrl as Uri).use {
                    if (holder.itemView.imageView.drawable.toBitmap().compress(Bitmap.CompressFormat.PNG,90,it)){
                        MainScope().launch { Toast.makeText(context, "存储成功", Toast.LENGTH_SHORT).show() }
                    }else{
                        MainScope().launch { Toast.makeText(context, "存储失败", Toast.LENGTH_SHORT).show() }
                    }
                }
    
            }
        }
    

    于是使用Kotlin中的协程,将方法名前加上suspend,方法内部使用 withContext(Dispatchers.IO){} 包裹起来,用来限定范围

  10. 最后则可以通过Lifecycle来调用

    viewLifecycleOwner.lifecycleScope.launch { saveImage() }
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值