当前位置:   article > 正文

【Kotlin】Android保存任意View为图片至系统图库—附demo源码_android 如果将自定义view生成图片

android 如果将自定义view生成图片

本文以少量的代码,演示了无需声明权限、仅10余行代码即可保存任意View为图片的简洁方法,demo源码链接附在文末

特别说明:

        本文采用分—总结构展示代码,即先展示局部代码,并说明其用法和作用;小节结尾处再给出该部分对应文件的完整代码布局XML文件在方法实现之后。

一、方法实现

        分两步完成:

  1. 转换View对象为Bitmap位图对象
  2. 将Bitmap位图对象保存为图片

        在MainActivity文件中:

1.将View转换为Bitmap位图

  1. /** 创建位图 */
  2. fun createViewBitmap(view: View): Bitmap? {
  3. val bitmap = Bitmap.createBitmap(
  4. view.width, view.height,
  5. Bitmap.Config.ARGB_8888
  6. )
  7. val canvas = Canvas(bitmap)
  8. view.draw(canvas)
  9. return bitmap
  10. }
Bitmap.createBitmap(参数1,参数2,参数3)

        这是内置的方法,直接调用即可将View对象转化为一个Bitmap位图对象

参数1:生成的Bitmap位图对象的宽,可使用当前View实际呈现的宽度,也可自行指定

参数2:生成的Bitmap位图对象的高,可使用当前View实际呈现的高度,也可自行指定

参数3:指定Bitmap位图对象的存储方案:本文采用Bitmap.Config.ARGB_8888

位图存储方案简介:A指alpha透明通道,RGB指红绿蓝三通道。

  1. ARGB_8888:四通道均采用8bit存储,质量最高,体积最大
  2. ARGB_4444:四通道均为4bit存储,据说失真较严重
  3. RGB_565:不包含透明通道,不支持透明度,但质量较好,体积仅ARGB_8888的一半
  4. ALPHA_8:不包含颜色值,仅存储alpha透明度

一般情况下,若无需透明度,选择RGB_565,可节省空间,需要透明度,选择ARGB_8888

更多细节敬请参见这位博主的文章


 2.保存Bitmap位图为图片

  1. /** 保存为图片 */
  2. fun saveImage(view: View) {
  3. // 调用上一步的转换位图函数
  4. val imageBit = createViewBitmap(view)
  5. // 保存至系统图库
  6. MediaStore.Images.Media.insertImage(contentResolver,imageBit, "picture_name", "demo_saveImage")
  7. }
MediaStore.Images.Media.insertImage(contentResolver, 参数1, 参数2, 参数3)

        也是一个内置的方法,在Activity中可以直接调用,contentResolver是固定传入对象。

参数1:位图对象Bitmap

参数2:图片名称,可以在系统图库的详情页面查看到

参数3:图片的描述信息


3.设置点击事件

  1. // 布局XML文件在后文
  2. // 分别绑定根布局和”保存图片”按钮
  3. val layout = findViewById<ConstraintLayout>(R.id.layout)
  4. val button = findViewById<Button>(R.id.save_button)
  5. // 设置“保存图片”按钮的点击
  6. button.setOnClickListener {
  7. saveImage(layout)
  8. }

   MainActivity的完整代码 

  1. class MainActivity : AppCompatActivity() {
  2. override fun onCreate(savedInstanceState: Bundle?) {
  3. super.onCreate(savedInstanceState)
  4. setContentView(R.layout.activity_main)
  5. // 分别绑定根布局和”保存图片”按钮
  6. val layout = findViewById<ConstraintLayout>(R.id.layout)
  7. val button = findViewById<Button>(R.id.save_button)
  8. // 设置“保存图片”按钮的点击
  9. button.setOnClickListener {
  10. saveImage(layout)
  11. }
  12. }
  13. /** 创建位图 */
  14. fun createViewBitmap(view: View): Bitmap? {
  15. val bitmap = Bitmap.createBitmap(
  16. view.width, view.height,
  17. Bitmap.Config.ARGB_8888
  18. )
  19. val canvas = Canvas(bitmap)
  20. view.draw(canvas)
  21. return bitmap
  22. }
  23. /** 保存为图片 */
  24. fun saveImage(view: View) {
  25. val imageBit = createViewBitmap(view)
  26. MediaStore.Images.Media.insertImage(contentResolver,imageBit, "picture_name", "demo_saveImage")
  27. }
  28. }

4.真机测试结果


二、布局设置

        本文使用约束布局,简单的设置了1个文本框,1个“保存图片”按钮。

1.设置“保存图片”按钮id为:save_button

2.设置根布局id为:layout

3.设置根布局的背景颜色为系统自带的白色:@color/white

第3步不是必须的,只是因为若不设置背景颜色,则默认透明,图片背景将显示为黑色,不利于观察)

        activity_main.xml文件的完整代码

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity"
  8. android:id="@+id/layout"
  9. android:background="@color/white">
  10. <TextView
  11. android:layout_width="wrap_content"
  12. android:layout_height="wrap_content"
  13. android:text="Hello World!"
  14. app:layout_constraintBottom_toBottomOf="parent"
  15. app:layout_constraintLeft_toLeftOf="parent"
  16. app:layout_constraintRight_toRightOf="parent"
  17. app:layout_constraintTop_toTopOf="parent" />
  18. <Button
  19. android:id="@+id/save_button"
  20. android:layout_width="match_parent"
  21. android:layout_height="wrap_content"
  22. android:text="保存图片"
  23. app:layout_constraintBottom_toBottomOf="parent"
  24. app:layout_constraintEnd_toEndOf="parent"
  25. app:layout_constraintStart_toStartOf="parent"
  26. app:layout_constraintTop_toTopOf="parent"
  27. app:layout_constraintVertical_bias="0.8" />
  28. </androidx.constraintlayout.widget.ConstraintLayout>

三、补充说明

        之所以无需声明存储权限,是因为此图片存储于共享存储空间中,这是系统提供的公共目录,由系统进行管理。详情敬请参阅官方说明文档官方说明文档官方说明文档

        在其他博主的文章中有反映到,此方法生成的图片不能在图库中立刻查看到,还需进行广播,通知图库进行更新,但实际测试结果中并未出现此问题。 

MediaStore.Images.Media.insertImage(contentResolver, 参数1, 参数2, 参数3)

        此方法在 API level 29 以上实际已被弃用,但并不是因为不安全而被弃用,此方法依旧是可以正常使用的,只是谷歌官方推出了可以更好控制生命周期的方法,有机会再写文章进行说明。

        除此方法外,还可将指定位置下的图片保存至系统图库。

MediaStore.Images.Media.insertImage(contentResolver, "image path", "title", "description")

如有任何疑问,请在评论区留言,我会努力回复。

demo源码链接如下:

github地址:https://github.com/darlingxyz/demo_saveImage

gitee地址:https://gitee.com/darlingxyz/demo_saveImage

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/262028
推荐阅读
相关标签
  

闽ICP备14008679号