Giter Club home page Giter Club logo

crop's Introduction

CropImageView


๐Ÿ˜Dependency

Lastest Version : 1.0.0

more (Maven, sbt, leiningen)

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
dependencies {
    implementation 'com.github.KangTaeJong98:Crop:$version'
}

๐Ÿ˜Š Introduce

CropImageView

  • ์ด๋ฏธ์ง€๋ฅผ ํ™•๋Œ€ ์ด๋™ ํ›„ ์›ํ•˜๋Š” ๋ถ€๋ถ„์„ ์ž๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • After zooming in and moving the image, you can cut the desired part.

0

1234


CropImageView

class CropImageView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0
): ShapeableImageView(context, attrs, defStyle) {
    private val gestureListener by lazy {
        object : GestureListener(0F, 0F, 0F) {
            private val dragMatrix by lazy { Matrix() }
            private val zoomMatrix by lazy { Matrix() }

            override fun onDragStart(view: View, event: MotionEvent) {
                dragMatrix.set(imageMatrix)
            }

            override fun onDrag(view: View, event: MotionEvent, movementX: Float, movementY: Float) {
                val values = MatrixValue(dragMatrix)
                val matrixWidth = drawable.intrinsicWidth * values.matrixWidthScale
                val matrixHeight = drawable.intrinsicHeight * values.matrixHeightScale

                val translationX = when {
                    movementX + values.matrixX + matrixWidth <= measuredWidth -> {
                        measuredWidth - values.matrixX - matrixWidth
                    }
                    movementX + values.matrixX >= 0F -> {
                        -values.matrixX
                    }
                    else -> {
                        movementX
                    }
                }
                val translationY = when {
                    movementY + values.matrixY + matrixHeight <= measuredHeight -> {
                        measuredHeight - values.matrixY - matrixHeight
                    }
                    movementY + values.matrixY >= 0F -> {
                        -values.matrixY
                    }
                    else -> {
                        movementY
                    }
                }

                imageMatrix = Matrix(dragMatrix).apply {
                    postTranslate(translationX, translationY)
                }
            }

            override fun onZoomStart(view: View, event: MotionEvent) {
                zoomMatrix.set(imageMatrix)
            }

            override fun onZoom(view: View, event: MotionEvent, scale: Float) {
                val values = MatrixValue(zoomMatrix)
                val matrixWidth = drawable.intrinsicWidth * values.matrixWidthScale
                val matrixHeight = drawable.intrinsicHeight * values.matrixHeightScale

                if (matrixWidth*scale < measuredWidth || matrixHeight*scale < measuredHeight) {
                    return
                }

                val movementLeft = twoPoint.x - values.matrixX
                val movementRight = values.matrixX + matrixWidth - twoPoint.x
                val movementTop = twoPoint.y - values.matrixY
                val movementBottom = values.matrixY + matrixHeight - twoPoint.y

                val imageLeft = twoPoint.x - movementLeft*scale
                val imageRight = twoPoint.x + movementRight*scale
                val imageTop = twoPoint.y - movementTop*scale
                val imageBottom = twoPoint.y + movementBottom*scale

                val translationX = when {
                    imageLeft > 0 -> {
                        -imageLeft
                    }
                    imageRight < measuredWidth -> {
                        measuredWidth - imageRight
                    }
                    else -> {
                        0F
                    }
                }
                val translationY = when {
                    imageTop > 0 -> {
                        -imageTop
                    }
                    imageBottom < measuredHeight -> {
                        measuredHeight - imageBottom
                    }
                    else -> {
                        0F
                    }
                }

                imageMatrix = Matrix(zoomMatrix).apply {
                    postScale(scale, scale, twoPoint.x, twoPoint.y)
                    postTranslate(translationX, translationY)
                }
            }

            override fun onRotate(view: View, event: MotionEvent, degree: Float) {

            }
        }
    }

    init {
        adjustViewBounds = true
        scaleType = ScaleType.MATRIX
        setOnTouchListener(gestureListener)

        viewTreeObserver.addOnGlobalLayoutListener {
            if (drawable is BitmapDrawable) {
                setImageCenter()
            }
        }
    }

    private fun setImageCenter() {
        val imageRectF = RectF(0F, 0F, drawable.intrinsicWidth.toFloat(), drawable.intrinsicHeight.toFloat())

        val viewRectF = if (bitmap.width > bitmap.height) {
            val scale = measuredHeight.toFloat() / drawable.intrinsicHeight.toFloat()
            val scaledWidth = drawable.intrinsicWidth.toFloat() * scale
            val x = (scaledWidth - measuredWidth) / 2F
            RectF(-x, 0F, measuredWidth + x, measuredHeight.toFloat())
        } else {
            val scale = measuredWidth.toFloat() / drawable.intrinsicWidth.toFloat()
            val scaledHeight = drawable.intrinsicHeight.toFloat() * scale
            val y = (scaledHeight - measuredHeight) / 2F
            RectF(0F, -y, measuredWidth.toFloat(), measuredHeight + y)
        }

        imageMatrix = Matrix(imageMatrix).apply {
            setRectToRect(imageRectF, viewRectF, Matrix.ScaleToFit.CENTER)
        }
    }

    val croppedBitmap: Bitmap
        get() {
            val values = MatrixValue(imageMatrix)

            return Bitmap.createBitmap(
                bitmap,
                abs(values.matrixX/values.matrixWidthScale).toInt(),
                abs(values.matrixY/values.matrixHeightScale).toInt(),
                (measuredWidth/values.matrixWidthScale + 0.5).toInt(),
                (measuredHeight/values.matrixHeightScale + 0.5).toInt()
            )
        }

    private val bitmap: Bitmap
        get() {
            return (drawable as BitmapDrawable).bitmap
        }

    class MatrixValue(matrix: Matrix) {
        private val values by lazy { FloatArray(9) }

        init {
            matrix.getValues(values)
        }

        val matrixX: Float
            get() {
                return values[2]
            }

        val matrixY: Float
            get() {
                return values[5]
            }

        val matrixWidthScale: Float
            get() {
                return values[0]
            }

        val matrixHeightScale: Float
            get() {
                return values[4]
            }
    }
}

crop's People

Contributors

kangtaejong98 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.