簡體   English   中英

從圖庫中選擇一張圖片作為畫布背景 [Android]

[英]Choose an image from gallery as Canvas background [Android]

在畫布上完成繪圖后,我已成功保存到畫廊,但現在我需要從廚房中打開一個圖像(例如我的舊繪圖)並將其用作背景,經過一番搜索后,沒有任何答案可以幫助我。 我已經開始嘗試這樣做,但是我如何實現它的任何建議或解決方案都會很棒。

有我的 Canvas 自定義視圖:

(READ 和 WRITE 權限已在另一個類中授予和處理)

    var drawingColor: Int = ResourcesCompat.getColor(resources, R.color.colorBlack, null)
    var strokeDrawWidth: Float = 12f

    private var path = Path()

    private val paths = ArrayList<Triple<Path, Int, Float>>()
    private val undonePaths = ArrayList<Triple<Path, Int, Float>>()

    private val extraCanvas: Canvas? = null

    private var bitmapBackground: Bitmap? = null

    private var motionTouchEventX = 0f
    private var motionTouchEventY = 0f

    private var currentX = 0f
    private var currentY = 0f

    private val touchTolerance = ViewConfiguration.get(context).scaledTouchSlop

    private val paint = Paint().apply {
        color = drawingColor
        isAntiAlias = true
        isDither = true
        style = Paint.Style.STROKE
        strokeJoin = Paint.Join.ROUND
        strokeCap = Paint.Cap.ROUND
        strokeWidth = strokeDrawWidth
    }

    fun loadCanvasBackground(bitmap: Bitmap) {
        bitmapBackground = bitmap
        invalidate()
    }

    fun saveCanvasDrawing() {
        canvasCustomView.isDrawingCacheEnabled = true
        val extraBitmap: Bitmap = canvasCustomView.drawingCache
        MediaStore.Images.Media.insertImage(context.contentResolver, extraBitmap, "drawing", "Paint R")
    }

    fun resetCanvasDrawing() {
        path.reset()
        paths.clear()
        invalidate()
    }

    fun undoCanvasDrawing() {
        if (paths.size > 0) {
            undonePaths.add(paths.removeAt(paths.size - 1))
            invalidate()
        } else {
            Log.d("UNDO_ERROR", "Something went wrong with UNDO action")
        }
    }

    fun redoCanvasDrawing() {
        if (undonePaths.size > 0) {
            paths.add(undonePaths.removeAt(undonePaths.size - 1))
            invalidate()
        } else {
            Log.d("REDO_ERROR", "Something went wrong with REDO action")
        }
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        if (bitmapBackground != null) {
            extraCanvas?.drawBitmap(bitmapBackground!!, 0f, 0f, paint)
        }

        for (p in paths) {
            paint.strokeWidth = p.third
            paint.color = p.second
            canvas?.drawPath(p.first, paint)
        }
        paint.color = drawingColor
        paint.strokeWidth = strokeDrawWidth
        canvas?.drawPath(path, paint)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event == null)
            return false

        motionTouchEventX = event.x
        motionTouchEventY = event.y

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                undonePaths.clear()
                path.reset()
                path.moveTo(motionTouchEventX, motionTouchEventY)
                currentX = motionTouchEventX
                currentY = motionTouchEventY
                invalidate()
            }

            MotionEvent.ACTION_MOVE -> {
                val distanceX = abs(motionTouchEventX - currentX)
                val distanceY = abs(motionTouchEventY - currentY)

                if (distanceX >= touchTolerance || distanceY >= touchTolerance) {
                    path.quadTo(
                        currentX,
                        currentY,
                        (motionTouchEventX + currentX) / 2,
                        (currentY + motionTouchEventY) / 2
                    )
                    currentX = motionTouchEventX
                    currentY = motionTouchEventY
                }
                invalidate()
            }

            MotionEvent.ACTION_UP -> {
                path.lineTo(currentX, currentY)
                extraCanvas?.drawPath(path, paint)
                paths.add(Triple(path, drawingColor, strokeDrawWidth))
                path = Path()
            }
        }
        return true
    }

    override fun isSaveEnabled(): Boolean {
        return true
    }

所以沒有人回答,經過一些搜索和實驗,我得到了可行的解決方案,如果您遇到相同的情況,請使用它或根據您的需要進行調整

(答案基於我的問題中的代碼 - 所以如果你錯過了一些依賴項,請檢查它)

  1. 使用ACTIVITY 中畫廊操作的請求代碼初始化伴隨對象
 companion object {
        private const val GALLERY_REQUEST_CODE = 102 
    }
  1. 創建一種從圖庫中選擇圖像的方法(您需要接收 Uri )
    private fun pickFromGallery() {
            val intent = Intent(Intent.ACTION_PICK)
            intent.type = "image/*"
            val imageTypes = arrayOf("image/jpeg", "image/png")
            intent.putExtra(Intent.EXTRA_MIME_TYPES, imageTypes)
            startActivityForResult(intent, GALLERY_REQUEST_CODE)
        }
  1. 比您需要覆蓋onActivityResult()方法來接收您的 Uri 並將其發送到自定義視圖
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == GALLERY_REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                val uri: Uri? = data?.data
                if (uri != null) {
                    val bitmap = MediaStore.Images.Media.getBitmap(this.contentResolver, uri)
                    canvasCustomView.loadCanvasBackground(bitmap)
                }
            }
        }
    }
  1. 現在在onDraw()方法(在您的自定義視圖中)您需要使用 .drawBitmap 將您收到的 Uri aka 位圖設置為畫布的背景
 override fun onDraw(canvas: Canvas?) {
        if (bitmapBackground != null) {
            canvas?.drawBitmap(bitmapBackground!!, 0f, 0f, paint)
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM