旋转的 ImageView 边缘不平滑(锯齿状)
Rotated ImageView edges are not smooth (jagged)
示例 NG ImageView
:NG Rotated ImageView
在 iOS 中,我可以通过 view.layer.allowsEdgeAntialiasing = true
轻松解决这个锯齿状边缘问题。在 Android 中解决此问题的最佳方法是什么?
我已经尝试过的:
我参考了这个 post 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" />
预期结果:平滑(抗锯齿)边缘
实际结果:边缘不平滑(锯齿状)
所以经过一段时间的试验,这是我能达到的最好结果:
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
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() {
//
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) 如果您有更好的解决方案,请务必comment/share出出主意!谢谢^^
示例 NG ImageView
:NG Rotated ImageView
在 iOS 中,我可以通过 view.layer.allowsEdgeAntialiasing = true
轻松解决这个锯齿状边缘问题。在 Android 中解决此问题的最佳方法是什么?
我已经尝试过的:
我参考了这个 post 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" />
预期结果:平滑(抗锯齿)边缘
实际结果:边缘不平滑(锯齿状)
所以经过一段时间的试验,这是我能达到的最好结果:
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
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() {
//
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) 如果您有更好的解决方案,请务必comment/share出出主意!谢谢^^