如何在桌面上使用Kotlin Compose时从硬盘加载图片?
其他答案已经过时,根据Compose 1.0.0-beta5版本,您应该执行以下操作:
Image(painterResource("image.jpg"))
如果您只想加载位图,则可以使用以下代码:
val bitmap = useResource("image.jpg") { loadImageBitmap(it) }
只需要文件名(不需要完整路径),但请确保您的资源在 src/main/resources/image.jpg
中。
你可以使用这个函数获取 ImageAsset。
fun imageFromFile(file: File): ImageAsset {
return org.jetbrains.skia.Image.makeFromEncoded(file.readBytes()).asImageAsset()
}
完整示例:
import androidx.compose.desktop.Window
import androidx.compose.foundation.Image
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.ImageAsset
import androidx.compose.ui.graphics.asImageAsset
import java.io.File
fun main() = Window {
val file = File("D:\\images\\my_image.PNG")
val image = remember { imageFromFile(file) }
Image(asset = image)
}
fun imageFromFile(file: File): ImageAsset {
return org.jetbrains.skia.Image.makeFromEncoded(file.readBytes()).asImageAsset()
}
试一试这个:
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.res.loadImageBitmap
import java.io.File
val file = File(path)
val imageBitmap: ImageBitmap = remember(file) {
loadImageBitmap(file.inputStream())
}
Image(
painter = BitmapPainter(image = imageBitmap),
contentDescription = null
)
这对我有用。
Image(bitmap = imageFromResource("image.png"),
"image",
)
contentDescription
是必需的,但可以是任何您喜欢的内容。您还可以添加修饰符,例如
val imageModifier = Modifier
.height(240.dp)
.fillMaxWidth()
.clip(RoundedCornerShape(12.dp))
Image(bitmap = imageFromResource("header.png"),
"image",
imageModifier,
contentScale = ContentScale.Fit
)
Image.asImageBitmap() 已经过时。请使用新的 Image.toComposeImageBitmap()。截至目前 (2022年4月1日),它尚未被弃用:
@Composable
fun CanvasArea2() {
val image = remember { imageFromFile(File("C:/Users/Admin/Desktop/banana.png")) }
Canvas(modifier = Modifier.background(color = Color(0xFFFFFFFF))) {
drawImage(image)
}
}
fun imageFromFile(file: File): ImageBitmap {
return org.jetbrains.skia.Image.makeFromEncoded(file.readBytes()).toComposeImageBitmap()
}
从文档中得知:异步加载设备存储或网络图片
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.loadImageBitmap
import androidx.compose.ui.res.loadSvgPainter
import androidx.compose.ui.res.loadXmlImageVector
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.singleWindowApplication
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.xml.sax.InputSource
import java.io.File
import java.io.IOException
import java.net.URL
fun main() = singleWindowApplication {
val density = LocalDensity.current
Column {
AsyncImage(
load = { loadImageBitmap(File("sample.png")) },
painterFor = { remember { BitmapPainter(it) } },
contentDescription = "Sample",
modifier = Modifier.width(200.dp)
)
AsyncImage(
load = { loadSvgPainter("https://github.com/JetBrains/compose-jb/raw/master/artwork/idea-logo.svg", density) },
painterFor = { it },
contentDescription = "Idea logo",
contentScale = ContentScale.FillWidth,
modifier = Modifier.width(200.dp)
)
AsyncImage(
load = { loadXmlImageVector(File("compose-logo.xml"), density) },
painterFor = { rememberVectorPainter(it) },
contentDescription = "Compose logo",
contentScale = ContentScale.FillWidth,
modifier = Modifier.width(200.dp)
)
}
}
@Composable
fun <T> AsyncImage(
load: suspend () -> T,
painterFor: @Composable (T) -> Painter,
contentDescription: String,
modifier: Modifier = Modifier,
contentScale: ContentScale = ContentScale.Fit,
) {
val image: T? by produceState<T?>(null) {
value = withContext(Dispatchers.IO) {
try {
load()
} catch (e: IOException) {
// instead of printing to console, you can also write this to log,
// or show some error placeholder
e.printStackTrace()
null
}
}
}
if (image != null) {
Image(
painter = painterFor(image!!),
contentDescription = contentDescription,
contentScale = contentScale,
modifier = modifier
)
}
}
/* Loading from file with java.io API */
fun loadImageBitmap(file: File): ImageBitmap =
file.inputStream().buffered().use(::loadImageBitmap)
fun loadSvgPainter(file: File, density: Density): Painter =
file.inputStream().buffered().use { loadSvgPainter(it, density) }
fun loadXmlImageVector(file: File, density: Density): ImageVector =
file.inputStream().buffered().use { loadXmlImageVector(InputSource(it), density) }
/* Loading from network with java.net API */
fun loadImageBitmap(url: String): ImageBitmap =
URL(url).openStream().buffered().use(::loadImageBitmap)
fun loadSvgPainter(url: String, density: Density): Painter =
URL(url).openStream().buffered().use { loadSvgPainter(it, density) }
fun loadXmlImageVector(url: String, density: Density): ImageVector =
URL(url).openStream().buffered().use { loadXmlImageVector(InputSource(it), density) }
/* Loading from network with Ktor client API (https://ktor.io/docs/client.html). */
/*
suspend fun loadImageBitmap(url: String): ImageBitmap =
urlStream(url).use(::loadImageBitmap)
suspend fun loadSvgPainter(url: String, density: Density): Painter =
urlStream(url).use { loadSvgPainter(it, density) }
suspend fun loadXmlImageVector(url: String, density: Density): ImageVector =
urlStream(url).use { loadXmlImageVector(InputSource(it), density) }
@OptIn(KtorExperimentalAPI::class)
private suspend fun urlStream(url: String) = HttpClient(CIO).use {
ByteArrayInputStream(it.get(url))
}
*/
import org.jetbrains.skia.Image
// ...
Image(
contentDescription = "image",
bitmap = Image.Companion.makeFromEncoded(imageBytes).toComposeImageBitmap()
)