Android 화면 캡쳐 방법 그리고 저장하기- View, 전체화면, RecyclerView

✨ 개요

앱에서 화면을 캡쳐하는 방법은 무엇을 찍고 싶은지에 따라 달라집니다.


1. 특정 View 캡처

fun captureView(view: View, config: Bitmap.Config = Bitmap.Config.ARGB_8888): Bitmap {
    val bmp = Bitmap.createBitmap(view.width, view.height, config)
    val canvas = Canvas(bmp)
    view.draw(canvas)
    return bmp
}

2. Activity 루트 뷰 (앱 화면 스냅샷)

fun captureActivity(activity: Activity): Bitmap {
    val root = activity.window.decorView.rootView
    val bmp = Bitmap.createBitmap(root.width, root.height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bmp)
    root.draw(canvas)
    return bmp
}

3. RecyclerView “전체 길이” 캡쳐 (보이는 영역을 넘어 전체 스크린샷)

fun captureRecyclerViewAll(rv: RecyclerView): Bitmap {
    val adapter = rv.adapter ?: error("No adapter")
    val widthSpec = View.MeasureSpec.makeMeasureSpec(rv.width, View.MeasureSpec.EXACTLY)
    var totalHeight = 0

    // 높이 계산(주의: 대용량이면 메모리 크래시 가능)
    for (i in 0 until adapter.itemCount) {
        val vh = adapter.createViewHolder(rv, adapter.getItemViewType(i))
        adapter.onBindViewHolder(vh, i)
        vh.itemView.measure(widthSpec, View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED))
        totalHeight += vh.itemView.measuredHeight
    }

    val bmp = Bitmap.createBitmap(rv.width, totalHeight, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bmp)
    var y = 0
    for (i in 0 until adapter.itemCount) {
        val vh = adapter.createViewHolder(rv, adapter.getItemViewType(i))
        adapter.onBindViewHolder(vh, i)
        vh.itemView.measure(widthSpec, View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED))
        vh.itemView.layout(0, 0, vh.itemView.measuredWidth, vh.itemView.measuredHeight)
        canvas.save()
        canvas.translate(0f, y.toFloat())
        vh.itemView.draw(canvas)
        canvas.restore()
        y += vh.itemView.measuredHeight
    }
    return bmp
}

4. 캡쳐한 Bitmap (갤러리 노출) - MediaStore(Android 10+)

기본 옵션

fun saveToGallery(context: Context, bmp: Bitmap, displayName: String = "capture_${System.currentTimeMillis()}.jpg") {
    val values = ContentValues().apply {
        put(MediaStore.Images.Media.DISPLAY_NAME, displayName)
        put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
        put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/Screenshots")
    }
    val uri = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values) ?: return
    context.contentResolver.openOutputStream(uri)?.use { out ->
        bmp.compress(Bitmap.CompressFormat.JPEG, 90, out)
        out.flush()
    }
}

5. 주의사항


6. 결론



Related Posts