【问题标题】:Rotated ImageView edges are not smooth (jagged)旋转的 ImageView 边缘不平滑(锯齿状)
【发布时间】:2019-04-04 01:17:07
【问题描述】:

样本 NG ImageView: NG Rotated ImageView

在 iOS 中,我可以通过view.layer.allowsEdgeAntialiasing = true 轻松解决这个锯齿状边缘问题。在 Android 中解决此问题的最佳方法是什么?

我已经尝试过的:
我参考了这篇帖子Bitmap not drawn anti-aliased并设置了android:layerType="software",但结果仍然是NG。

<ImageView
        android:id="@+id/imageView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layerType="software"
        android:rotation="5"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/pic" />

预期结果:平滑(抗锯齿)边缘
实际结果:边缘不光滑(锯齿状)

【问题讨论】:

    标签: android rotation imageview antialiasing


    【解决方案1】:

    所以经过一段时间的实验,这是我能做到的最好的:

    1) 测试输出: NG vs OK

    2) NG输出源

    *xml 仅(在 ConstraintLayout 下)

    <ImageView android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               app:layout_constraintTop_toTopOf="parent"
               app:layout_constraintStart_toStartOf="parent"
               app:layout_constraintEnd_toEndOf="parent"
               app:layout_constraintBottom_toBottomOf="parent"
               android:id="@+id/test3"
               app:srcCompat="@drawable/sampleImg"
               android:rotation="5"/>
    

    3) OK 输出源

    *xml(在ConstraintLayout下)

    <test.ntfry.imageview_rotate_antialias.MyImageView
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               app:layout_constraintTop_toTopOf="parent"                                   
               app:layout_constraintStart_toStartOf="parent"                                    
               app:layout_constraintEnd_toEndOf="parent"
               app:layout_constraintBottom_toBottomOf="parent"
               android:id="@+id/test2"/>
    

    *自定义 ImageView 类

    class MyImageView : AppCompatImageView {
    
        private val mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        private val mMatrix = Matrix()
        private var mRotatedBitmap: Bitmap? = null
        private val mRotation = 5F
    
        constructor(context: Context) : super(context, null) {
            init()
        }
        constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
            init()
        }
        constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
            init()
        }
    
        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
            setMeasuredDimension(mRotatedBitmap!!.width, mRotatedBitmap!!.height)
        }
    
        override fun onDraw(canvas: Canvas?) {
            super.onDraw(canvas)
            canvas?.drawBitmap(mRotatedBitmap!!, 0f, 0f, mPaint)
        }
    
        private fun init() {
            // https://stackoverflow.com/questions/14378573/bitmap-not-drawn-anti-aliased
            setLayerType(LAYER_TYPE_SOFTWARE, null)
    
            // get source image and set-apply rotation through matrix
            val sourceBitmap = BitmapFactory.decodeResource(resources, R.drawable.sampleImg)
            mMatrix.postRotate(mRotation)
            mRotatedBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.width, sourceBitmap.height, mMatrix, true)
        }
    }
    

    4) 如果您有更好的解决方案,请务必评论/分享您的想法!谢谢^^

    【讨论】:

      猜你喜欢
      • 2019-04-30
      • 2019-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-10
      • 2016-01-27
      相关资源
      最近更新 更多