在设置新位图之前如何在平移和缩放后将图像视图重置为原始/干净状态

问题描述 投票:0回答:1

我尝试过 Stackoverflow 系统提供的许多类似问题,但它们适用于其他场景。我不使用画布,我使用 Matrix 进行缩放和平移,但与scrollBy 和 imageview.scaleX、imageview.scaleY 结合使用。

问题是我想替换 ImageView 中的位图,但是替换后它采用与前一个位图相同的位置和缩放状态。

我尝试执行 ScrollTo(0,0) 来重置位置。尝试了translateX(0)、translateY(0)。尝试过 setX(0), setY(0)

尝试执行setImageMatrix(originalM),其中originalM是创建时的imageview.imageMatrix。尝试过 imageview.imageMatrix = Matrix()

尝试 imageview.setScaleType(ImageView.ScaleType.CENTER_CROP) 然后 imageview.setScaleType(ImageView.ScaleType.MATRIX)

为了让读者受益,这是我代码的一部分。 您会注意到我在场景后面平移和缩放矩阵,但不会使图像视图无效。我希望用户看到视图中的更改,而不是矩阵中的更改。我正在尝试在 PX 中缩放和平移矩阵(这部分无法正常工作,但超出了本问题的范围。使用此矩阵可能是问题的一部分,但我无法将其删除,因为用于代码中的另一个函数和其他主题/问题)

布局:

<FrameLayout
    android:id="@+id/frame"
    android:layout_width="350dp"
    android:layout_height="500dp"
    android:layout_marginStart="30dp"
    android:layout_marginTop="2dp"
    android:layout_marginEnd="30dp"
    android:background="@drawable/image_border"
    android:visibility="visible"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/button_layout">

    
    <ImageView
        android:id="@+id/pdfview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:contentDescription="@string/pdf"
        android:cropToPadding="true"
        android:scaleType="matrix"
        app:layout_constraintDimensionRatio="1:1"
        app:srcCompat="@color/material_dynamic_neutral80" />

    <!--android:scaleType="centerCrop"-->


</FrameLayout>

缩放:

slider.addOnChangeListener { slider, value, fromUser ->
        // Responds to when slider's value is changed
        tv = "Zoom Value:\n${value.format(2)}%"
        zoom.text = tv
        m = pdfview.imageMatrix
        scaleX = 1 + value / 100
        scaleY = 1 + value / 100

        // Responds to when slider's value is changed
        pdfview.scaleX = scaleX
        pdfview.scaleY = scaleY
        scrollX = pdfview.scrollX
        scrollY = pdfview.scrollY
        m.setScale(scaleX, scaleY, centerX, centerY)
        m.postTranslate(
            -(scrollX).toInt().toFloat().px,
            -(scrollY).toInt().toFloat().px
        )
    }

扩展功能

private val Float.px: Float get() = (this * getSystem().displayMetrics.density)

潘:

     pdfview.setOnTouchListener { v, event ->

        val currentX: Float
        val currentY: Float
        
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                preX = event.x
                preY = event.y
            }

            MotionEvent.ACTION_MOVE -> {
                currentX = event.x
                currentY = event.y
                
                    pdfview.scrollBy((preX - currentX).toInt(), (preY - currentY).toInt())
                    m.postTranslate( 
                        -(preX - currentX).toInt().toFloat().px,
                        -(preY - currentY).toInt().toFloat().px
                    )
                    preX = currentX
                    preY = currentY
                
            }

            MotionEvent.ACTION_UP -> {
                currentX = event.x
                currentY = event.y
                    pdfview.scrollBy((preX - currentX).toInt(), (preY - currentY).toInt())
                    m.postTranslate(
                        -(preX - currentX).toInt().toFloat().px,
                        -(preY - currentY).toInt().toFloat().px
                    )
                
            }
        }
        true
    }

图像视图位图:

 @Throws(IOException::class)
private fun openPdfFromStorage(uri: Uri) {
    var FILE_NAME = getFileName(uri)//"temp${Date()}.pdf"
    if (FILE_NAME == null) FILE_NAME = "temp${Date()}.pdf"
    val fileCopy = File(cacheDir, FILE_NAME) //anything as the name
    copyToCache(fileCopy, uri) /////////// Function not shown. Reads full file from Uri and place it in memory
    // Get a page from the PDF doc by calling 'open'
    val fileDescriptor = ParcelFileDescriptor.open(
        fileCopy,
        ParcelFileDescriptor.MODE_READ_ONLY
    )
    mPdfRenderer = PdfRenderer(fileDescriptor)
    pdfpages = mPdfRenderer.pageCount
    pdfnum = 0

    val mPdfPage = mPdfRenderer.openPage(pdfnum)

    val bitmap = Bitmap.createBitmap(
        pdfview.width, //bmWidth,
        pdfview.height, //bmHeight,
        Bitmap.Config.ARGB_8888
    ) //Not RGB, but ARGB
    mPdfPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)

    pdfview.setImageBitmap(bitmap)
    ///////////
    // WHEN THIS IS EXECUTED OVER A PREVIOUSLY USED IMAGEVIEW THE BITMAP IS SHOWN WITH THE SAME POSITION AND SCALE OF THE PREVIOUS BITMAP
    ///////////
    pdfview.setScaleType(ImageView.ScaleType.CENTER_CROP)
    pdfview.setScaleType(ImageView.ScaleType.MATRIX)
    m = pdfview.imageMatrix
    mPdfPage.close()
    pbounds = getImageBounds(pdfview) //imageView.imageMatrix.mapRect(bounds, RectF(drawable.bounds))
    centerX = pbounds.centerX()
    centerY = pbounds.centerY()
    
}
matrix imageview position reset
1个回答
0
投票

一旦我发现如何正确地使用矩阵移动机制,就很简单了:

在替换图像之前,将当前图像移动到原点。 以下代码会将图像平移回原点。

        val sX = scrollX //current X coord.
        val sY = scrollY //current Y coord. 
        val pX = pscrollX //previous X coord.
        val pY = pscrollY //previous Y coord.

        m.postTranslate(-(pX - sX), -(pY - sY)) 
        pdfview.imageMatrix = m
        val f = FloatArray(9)
        m.getValues(f)
        pscrollX = f[Matrix.MTRANS_X]
        pscrollY = f[Matrix.MTRANS_Y]

然后替换图像:

pdfview.imageMatrix = Matrix()
pdfview.scaleType = ImageView.ScaleType.MATRIX
pdfview.setImageBitmap(bitmap)
© www.soinside.com 2019 - 2024. All rights reserved.