XML
文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Activity
代码
const val TAG = "Yang"
class MainActivity : AppCompatActivity() {
var screenWidth = 0
var screenHeight = 0
var mImageView: ImageView ?= null
var tempBitmap: Bitmap? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mImageView = findViewById(R.id.iv)
screenWidth = resources.displayMetrics.widthPixels
screenHeight = resources.displayMetrics.heightPixels
val tempRect = RectF(0f, 0f, screenWidth.toFloat() / 2, screenHeight.toFloat() / 2)
CoroutineScope(Dispatchers.IO).launch {
tempBitmap = getBitmap(resources, tempRect, R.drawable.fake)
withContext(Dispatchers.Main) {
mImageView?.post {
tempBitmap?.let {
mImageView?.setImageBitmap(splitAndDrawBitmapWithMatrix(it, 10, 10))
}
}
}
}
}
}
fun getBitmap(resources : Resources, destRect : RectF, imageId: Int): Bitmap? {
var imageWidth = -1
var imageHeight = -1
val preOption = BitmapFactory.Options().apply {
inJustDecodeBounds = true
BitmapFactory.decodeResource(resources, imageId, this)
}
imageWidth = preOption.outWidth
imageHeight = preOption.outHeight
val scaleMatrix = Matrix()
var srcRect = RectF(0f, 0f, imageWidth.toFloat(), imageHeight.toFloat())
scaleMatrix.setRectToRect(srcRect, destRect, Matrix.ScaleToFit.CENTER)
scaleMatrix.mapRect(srcRect)
val finalOption = BitmapFactory.Options().apply {
if (imageHeight > 0 && imageWidth > 0) {
inPreferredConfig = Bitmap.Config.ARGB_8888
inSampleSize = calculateInSampleSize(
imageWidth,
imageHeight,
srcRect.width().toInt(),
srcRect.height().toInt()
)
}
}
return BitmapFactory.decodeResource(resources, imageId, finalOption)
}
fun calculateInSampleSize(fromWidth: Int, fromHeight: Int, toWidth: Int, toHeight: Int): Int {
var bitmapWidth = fromWidth
var bitmapHeight = fromHeight
if (fromWidth > toWidth|| fromHeight > toHeight) {
var inSampleSize = 1
while (bitmapWidth >= toWidth && bitmapHeight >= toHeight) {
bitmapWidth /= 2
bitmapHeight /= 2
inSampleSize *= 2
}
return inSampleSize
}
return 1
}
Canvas
平移方式绘制
- 保证每次从左上角原点开始绘制,每次绘制需要调用
canvas.save()
和canvas.restore()
fun splitAndDrawBitmapWithCanvas(input: Bitmap, rows: Int, cols: Int): Bitmap {
val width = input.width / cols
val height = input.height / rows
val output = Bitmap.createBitmap(input.width, input.height, input.config)
val canvas = Canvas(output)
val paint = Paint().apply {
isAntiAlias = true
isFilterBitmap = true
}
for (i in 0 until rows) {
for (j in 0 until cols) {
if ((i + j) % 2 == 0) {
val x = j * width
val y = i * height
val srcRect = Rect(x, y, x + width, y + height)
val destRect = Rect(0, 0, width, height)
canvas.save()
canvas.translate(x.toFloat(), y.toFloat())
canvas.drawBitmap(input, srcRect, destRect, paint)
canvas.restore()
}
}
}
return output
}
Rect
方式绘制
public void drawBitmap(@NonNull Bitmap bitmap,
@Nullable Rect src,
@NonNull Rect dst,
@Nullable Paint paint) {}
src
是原图中截取的矩形区域,如果设置为null
,则默认截取整个原图dst
是将 src
截取的图像绘制到Canvas
的哪个区域内
fun splitAndDrawBitmapWithRect(input: Bitmap, rows: Int, cols: Int): Bitmap {
val width = input.width / cols
val height = input.height / rows
val output = Bitmap.createBitmap(input.width, input.height, input.config)
val canvas = Canvas(output)
val paint = Paint().apply {
isAntiAlias = true
isFilterBitmap = true
}
for (i in 0 until rows) {
for (j in 0 until cols) {
if ((i + j) % 2 == 0) {
val x = j * width
val y = i * height
val srcRect = Rect(x, y, x + width, y + height)
val destRect = Rect(x, y, x + width, y + height)
canvas.drawBitmap(input, srcRect, destRect, paint)
}
}
}
return output
}
效果图