• Android图片涂鸦,Kotlin(1)


    Android图片涂鸦,Kotlin(1)

     

    1. import android.content.Context
    2. import android.graphics.Canvas
    3. import android.graphics.Color
    4. import android.graphics.Paint
    5. import android.graphics.Path
    6. import android.graphics.PointF
    7. import android.util.AttributeSet
    8. import android.util.Log
    9. import android.view.MotionEvent
    10. import androidx.appcompat.widget.AppCompatImageView
    11. class PaintView @JvmOverloads constructor(
    12. context: Context?,
    13. attrs: AttributeSet? = null,
    14. defStyleAttr: Int = 0
    15. ) : AppCompatImageView(context!!, attrs, defStyleAttr) {
    16. class DrawPath {
    17. var id: Long = 0L
    18. var path: Path? = null
    19. var paint: Paint? = null
    20. var points = ArrayList()
    21. }
    22. private var mPaint: Paint? = null
    23. private var mPath: Path? = null
    24. private var mDownX = 0f
    25. private var mDownY = 0f
    26. private var mTempX = 0f
    27. private var mTempY = 0f
    28. //默认的画笔宽度
    29. private var mPaintWidth = 10
    30. //默认画笔的颜色
    31. private var mColor = Color.RED
    32. private val mDrawPathList: ArrayList?
    33. private val mSavePathList: ArrayList?
    34. companion object {
    35. var WIDTH_INCREMENT = 15
    36. const val TAG = "PaintView"
    37. }
    38. init {
    39. mDrawPathList = ArrayList()
    40. mSavePathList = ArrayList()
    41. initPaint()
    42. }
    43. private fun initPaint() {
    44. mPaint = Paint()
    45. mPaint?.color = mColor
    46. mPaint?.isAntiAlias = true
    47. mPaint?.strokeWidth = mPaintWidth.toFloat()
    48. mPaint?.style = Paint.Style.STROKE
    49. }
    50. override fun onDraw(canvas: Canvas) {
    51. super.onDraw(canvas)
    52. if (!mDrawPathList.isNullOrEmpty()) {
    53. for (drawPath in mDrawPathList) {
    54. if (drawPath.path != null) {
    55. canvas.drawPath(drawPath.path!!, drawPath.paint!!)
    56. }
    57. drawPath.points.forEach {
    58. Log.d(TAG, "onDraw ${drawPath.id} ${it.x} ${it.y}")
    59. }
    60. }
    61. }
    62. }
    63. override fun onTouchEvent(event: MotionEvent): Boolean {
    64. when (event.action) {
    65. MotionEvent.ACTION_DOWN -> {
    66. Log.d(TAG, "ACTION_DOWN ${event.x} ${event.y}")
    67. mDownX = event.x
    68. mDownY = event.y
    69. //每次手指点下去作为一条新路径。
    70. mPath = Path()
    71. mPath?.moveTo(mDownX, mDownY)
    72. val drawPath = DrawPath()
    73. drawPath.id = System.currentTimeMillis()
    74. drawPath.paint = mPaint
    75. drawPath.path = mPath
    76. mDrawPathList?.add(drawPath)
    77. //新一轮绘制开始,保存点。
    78. drawPath.points.add(PointF(event.x, event.y))
    79. invalidate()
    80. mTempX = mDownX
    81. mTempY = mDownY
    82. }
    83. MotionEvent.ACTION_MOVE -> {
    84. //Log.d(TAG, "ACTION_MOVE ${event.x} ${event.y}")
    85. val moveX = event.x
    86. val moveY = event.y
    87. mPath?.quadTo(mTempX, mTempY, moveX, moveY)
    88. mDrawPathList?.filter {
    89. it.path == mPath
    90. }?.forEach {
    91. it.points.add(PointF(event.x, event.y))
    92. }
    93. invalidate()
    94. mTempX = moveX
    95. mTempY = moveY
    96. }
    97. //每次手指抬起重置画笔,不然画笔会保存之前设置的属性会引起bug。
    98. MotionEvent.ACTION_UP -> {
    99. Log.d(TAG, "ACTION_UP ${event.x} ${event.y}")
    100. initPaint()
    101. }
    102. }
    103. return true
    104. }
    105. /**
    106. * 撤销。
    107. */
    108. fun undo() {
    109. if (mDrawPathList != null && mDrawPathList.size >= 1) {
    110. mSavePathList?.add(mDrawPathList[mDrawPathList.size - 1])
    111. mDrawPathList.removeAt(mDrawPathList.size - 1)
    112. invalidate()
    113. }
    114. }
    115. /**
    116. * 反撤销,重新生效。
    117. */
    118. fun reundo() {
    119. if (!mSavePathList.isNullOrEmpty()) {
    120. mDrawPathList?.add(mSavePathList[mSavePathList.size - 1])
    121. mSavePathList.removeAt(mSavePathList.size - 1)
    122. invalidate()
    123. }
    124. }
    125. /**
    126. * 画笔颜色。
    127. *
    128. * @param color
    129. */
    130. fun setPaintColor(color: Int) {
    131. this.mColor = color
    132. mPaint?.color = this.mColor
    133. }
    134. /**
    135. * 画笔的宽度。
    136. */
    137. fun setPaintWidth(size: Int) {
    138. mPaintWidth += size
    139. mPaint?.strokeWidth = mPaintWidth.toFloat()
    140. }
    141. /**
    142. * 放大,改变画笔的宽度。线条变粗。
    143. */
    144. fun enlargePaintWidth() {
    145. mPaintWidth += WIDTH_INCREMENT
    146. mPaint?.strokeWidth = mPaintWidth.toFloat()
    147. }
    148. fun getDrawPath(): ArrayList? {
    149. return mDrawPathList
    150. }
    151. }

     

     

    1. "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. <com.pkg1115.PaintView
    9. android:id="@+id/paint_view"
    10. android:layout_width="match_parent"
    11. android:layout_height="match_parent"
    12. android:scaleType="fitCenter"
    13. android:src="@mipmap/p1"
    14. app:layout_constraintBottom_toBottomOf="parent"
    15. app:layout_constraintEnd_toEndOf="parent"
    16. app:layout_constraintStart_toStartOf="parent"
    17. app:layout_constraintTop_toTopOf="parent" />
    18. <RelativeLayout
    19. android:id="@+id/rl_left"
    20. android:layout_width="100dp"
    21. android:layout_height="wrap_content"
    22. app:layout_constraintStart_toStartOf="parent"
    23. app:layout_constraintTop_toTopOf="parent">
    24. <Button
    25. android:id="@+id/btn_undo"
    26. android:layout_width="match_parent"
    27. android:layout_height="60dp"
    28. android:text="撤销" />
    29. <Button
    30. android:id="@+id/btn_red"
    31. android:layout_width="match_parent"
    32. android:layout_height="60dp"
    33. android:layout_below="@id/btn_undo"
    34. android:text="红色" />
    35. <Button
    36. android:id="@+id/btn_green"
    37. android:layout_width="match_parent"
    38. android:layout_height="60dp"
    39. android:layout_below="@id/btn_red"
    40. android:text="绿色" />
    41. <Button
    42. android:id="@+id/btn_enlarge"
    43. android:layout_width="match_parent"
    44. android:layout_height="60dp"
    45. android:layout_below="@id/btn_green"
    46. android:text="放大" />
    47. RelativeLayout>
    48. androidx.constraintlayout.widget.ConstraintLayout>

     

     

     

     

     

    Android图形图像处理:添加涂鸦文字_android 在图片上涂鸦-CSDN博客文章浏览阅读2k次。先看运行效果: 关键的PaintView:package com.zhangphil;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graph..._android 在图片上涂鸦https://blog.csdn.net/zhangphil/article/details/87810653

     

  • 相关阅读:
    数据中心容灾考题
    Dynamics 365 重写自带按钮
    软件工程理论与实践 (吕云翔) 第五章 面向对象方法与UML课后习题及其答案解析
    LeetCode刷题笔记【25】:贪心算法专题-3(K次取反后最大化的数组和、加油站、分发糖果)
    趣学算法【第一章:算法之美】感悟(上)
    [入门到吐槽系列] Webix 10分钟入门 一 管理后台制作
    uvm组件
    【Spring(三)】熟练掌握Spring的使用
    CVPR 2022 | SharpContour:一种基于轮廓变形 实现高效准确实例分割的边缘细化方法
    QT JSON数据格式讲解
  • 原文地址:https://blog.csdn.net/zhangphil/article/details/134444295