Более конкретно, я получил изображение из URI с помощью Coil, затем преобразовал его в объект рисования, а затем преобразовал объект рисования в растровое изображение, затем преобразовал растровое изображение в массив байтов и, наконец, закодировал массив байтов в строку Base64.
При сохранении строки Base64 в файл кажется, что все получилось хорошо. Приложение не вылетает, имя файла появляется на экране и в инспекторе приложений. Я не уверен, что строка Base64 сохранена, потому что я не могу просмотреть содержимое файла.
Проблема возникает, когда мне нужно декодировать строку Base64, чтобы можно было просмотреть ее содержимое. .
Я разработал функцию, которая декодирует строку обратно в растровое изображение, чтобы я мог прочитать URI из файла. Однако приложение вылетает всякий раз, когда я пытаюсь это сделать.
Вот код, он написан на Kotlin, а пользовательский интерфейс разработан с помощью Jetpack Compose.
Код: Выделить всё
// Directory Of Saved Files
val directory = File(this.cacheDir, "images")
if (!directory.exists()) {
directory.mkdirs()
}
// Directory Converted To A List
var directoryFiles by remember { mutableStateOf(directory.listFiles()?.toList() ?: listOf())}
// Varaible Holding URI For The Image
var imageUri by remember { mutableStateOf(null) }
// Function That Converts The URI Into A Drawable And Then To A Bitmap
suspend fun convertToBitmap(): Bitmap {
val imageLoader = this.imageLoader
val request = ImageRequest.Builder(this)
.data(imageUri)
.build()
return (imageLoader.execute(request).drawable as BitmapDrawable).bitmap
}
// Function That Converts The Bitmap Into A Byte Array
suspend fun convertToBytes(): ByteArray {
val outputStream = ByteArrayOutputStream()
convertToBitmap().compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
return outputStream.toByteArray()
}
// Function That Encodes The Byte Array Into A Base64 String
suspend fun encodeToBase64(): String {
val bytes = convertToBytes()
return Base64.encodeToString(bytes, Base64.URL_SAFE)
}
// Function That Decodes The Base64 String Back To A Bitmap
fun decodeBase64(base64: String): Bitmap {
val bytes = Base64.decode(base64, Base64.URL_SAFE)
return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
}
// Launcher For The Image Picker
val imagePickerLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.PickVisualMedia(),
onResult = {uri ->
imageUri = uri
}
)
// Application Layout
Column(
modifier = Modifier
.fillMaxSize()
.padding(WindowInsets.systemBars.asPaddingValues()),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
) {
// Layout For Buttons
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
// Button That Launches The Image Picker
Button(onClick = {imagePickerLauncher.launch(
PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)
)}) { Text("Select Image") }
// Button That Encodes The Selected Image And Then Saves It To A File
Button(onClick = {
CoroutineScope(Dispatchers.IO).launch {
val file = File(directory, directoryFiles.size.toString())
file.writeText(encodeToBase64())
directoryFiles = directory.listFiles()?.toList() ?: listOf()
}}) { Text("Save Image") }
}
// UI Element That Displays The Selected Image A Later The Saved Image
AsyncImage(
model = imageUri,
contentDescription = null,
modifier = Modifier
.background(Color.LightGray)
.size(200.dp)
)
// Lazy Column That Displays The Save Files
LazyColumn(
verticalArrangement = Arrangement.spacedBy(10.dp)
) {
items(directoryFiles) {
/* List Item For Each File, When Clicked The Contents Of The File Are
Decoded Back To A Bitmap And The Image URI Is Retrieved */
Text(
it.name,
fontSize = 20.sp,
modifier = Modifier.clickable {
decodeBase64(it.readText())
imageUri = Uri.fromFile(it)
})
}
}
}
Любой вклад приветствуется.
Подробнее здесь: https://stackoverflow.com/questions/793 ... roid-using
Мобильная версия