프로젝트 개발 중, 결과 달성률 보고 페이지를 이미지로 저장하는 기능을 만들어야 했다.
함수를 이용하여
val captureImage = getScreenShotFromView(viewBinding.baseLayout)
val filename = "${System.currentTimeMillis()}.jpg"
//이미지 저장
if (captureImage!=null){
saveMediaToStorage(captureImage, filename)
}
이렇게 이미지 저장을 하도록 구현했지만, 저장된 화면은 그냥 까만 화면이었다.
이 문제는 내가 스크린 하려는 페이지가 아직 화면에 제대로 띄워지지 않은 상태에서 캡쳐가 되어서 생긴 문제였다.
이를 해결하기 위해 post 함수를 사용했다.
post 함수는 내가 저장하고자 하는 페이지가 화면에 완전히 띄워질 때까지 기다렸다가 명령을 실행할 수 있게 해주는 함수다.
viewBinding.image.setOnClickListener {
//이미지 캡쳐 해서 만들기
//post를 해야 검은 화면이 안 뜬다.
//->뷰가 Attach 되지 않았다면 될 때까지 runnable을 연기시켜 줍니다
viewBinding.baseLayout.post {
val captureImage = getScreenShotFromView(viewBinding.baseLayout)
val filename = "${System.currentTimeMillis()}.jpg"
//이미지 저장
if (captureImage!=null){
saveMediaToStorage(captureImage, filename)
}
}
}
post 함수 안에 캡쳐 함수를 넣었더니 의도대로 화면이 제대로 캡쳐되었다.
getScreenShotFromView
함수
//view를 캡쳐하는 함수
private fun getScreenShotFromView(v: View): Bitmap? {
// create a bitmap object
var screenshot: Bitmap? = null
try {
// inflate screenshot object
// with Bitmap.createBitmap it
// requires three parameters
// width and height of the view and
// the background color
screenshot = Bitmap.createBitmap(v.measuredWidth, v.measuredHeight, Bitmap.Config.ARGB_8888)
// Now draw this bitmap on a canvas
val canvas = Canvas(screenshot)
v.draw(canvas)
} catch (e: Exception) {
Log.e("GFG", "Failed to capture screenshot because:" + e.message)
}
// return the bitmap
return screenshot
}
saveMediaToStorage
함수
//이미지를 저장하는 함수
private fun saveMediaToStorage(bitmap: Bitmap, filename : String) {
// Generating a file name
// val filename = "${System.currentTimeMillis()}.jpg"
// Output stream
var fos: OutputStream? = null
// For devices running android >= Q
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// getting the contentResolver
this.contentResolver?.also { resolver ->
// Content resolver will process the contentvalues
val contentValues = ContentValues().apply {
// putting file information in content values
put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg")
put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
}
// Inserting the contentValues to
// contentResolver and getting the Uri
val imageUri: Uri? = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
// Opening an outputstream with the Uri that we got
fos = imageUri?.let { resolver.openOutputStream(it) }
}
} else {
// These for devices running on android < Q
val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
val image = File(imagesDir, filename)
fos = FileOutputStream(image)
}
fos?.use {
// Finally writing the bitmap to the output stream that we opened
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)
Toast.makeText(this , "Captured View and saved to Gallery" , Toast.LENGTH_SHORT).show()
}
}