Arjan van Wieringen
02/18/2023, 1:57 PMnativeCanvas
into a Bitmap during a drawWithContent
modifier, but readPixels
always returns false, and I don't know why:
drawContent()
val nativeCanvas = drawContext.canvas.nativeCanvas
val imageInfo = ImageInfo(
width = 1280,
height = 800,
colorInfo = ColorInfo(
colorType = ColorType.RGBA_8888,
alphaType = ColorAlphaType.PREMUL,
colorSpace = ColorSpace.sRGB
),
)
val bitmap = Bitmap()
if (!bitmap.setImageInfo(imageInfo)) {
println("Couldn't set imageInfo")
}
if (!bitmap.allocPixels()) {
println("Couldn't allocate pixels")
}
if (!nativeCanvas.readPixels(bitmap, 0, 0)) {
println("Couldn't read pixels") <-- this one returns false
}
Kirill Grouchnikov
02/18/2023, 2:52 PMKirill Grouchnikov
02/18/2023, 2:54 PMArjan van Wieringen
02/18/2023, 2:57 PMKirill Grouchnikov
02/18/2023, 3:04 PMKirill Grouchnikov
02/18/2023, 3:08 PMresolutionStrategy.eachDependency {
if (requested.group == "org.jetbrains.skiko") {
useVersion("0.0.0-SNAPSHOT")
because("Replacing for local development")
}
}
Kirill Grouchnikov
02/18/2023, 3:24 PMPictureHolder
Kirill Grouchnikov
02/18/2023, 3:25 PMKirill Grouchnikov
02/18/2023, 3:25 PMKirill Grouchnikov
02/18/2023, 3:27 PMSkiaLayer.awt.kt
Arjan van Wieringen
02/18/2023, 3:33 PMKirill Grouchnikov
02/18/2023, 3:35 PMArjan van Wieringen
02/18/2023, 3:35 PMKirill Grouchnikov
02/18/2023, 3:37 PMArjan van Wieringen
02/18/2023, 3:38 PMnativeCanvas
maybe?) and get these contents.
However, in your Aurora repository I also saw some sort of screenshot functionality if I am not mistaken?Kirill Grouchnikov
02/18/2023, 3:40 PMArjan van Wieringen
02/18/2023, 3:45 PMKirill Grouchnikov
02/18/2023, 3:47 PMKirill Grouchnikov
02/18/2023, 3:48 PMImageComposeScene
needs that intermediate layer somewhere in your real app, see if renderComposeScene
might fit your needs better,Kirill Grouchnikov
02/18/2023, 3:48 PMArjan van Wieringen
02/18/2023, 4:10 PMArjan van Wieringen
02/24/2023, 8:46 AMScreenshotContainer
which takes a special state object to trigger screenshots and a content lambda. When the screenshot is taken the content lambda is drawn inside an ImageComposeScrene
, which results in:Arjan van Wieringen
02/24/2023, 8:48 AMclass ScreenshotState {
private val _trigger = MutableSharedFlow<Unit>(
replay = 1,
extraBufferCapacity = 0,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val trigger = _trigger.asSharedFlow()
private val _latestScreenShot = MutableStateFlow<ImageBitmap?>(null)
val latestScreenShot = _latestScreenShot.asStateFlow()
fun takeScreenshot() {
_trigger.tryEmit(Unit)
}
fun renderContent(
width: Int,
height: Int,
density: Density,
content: @Composable () -> Unit
) {
val scene = ImageComposeScene(
width = width,
height = height,
density = density,
content = content
)
_latestScreenShot.update {
scene.render().toComposeImageBitmap()
}
}
}
@Composable
fun ScreenshotContainer(
screenshotState: ScreenshotState,
targetDensity: Density = Density(1f),
content: @Composable () -> Unit
) {
val density: Density = LocalDensity.current
var layoutCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
LaunchedEffect(screenshotState) {
screenshotState.trigger.collect {
if (layoutCoordinates != null) {
val scale = targetDensity.density / density.density
screenshotState.renderContent(
width = (layoutCoordinates!!.size.width * scale).toInt(),
height = (layoutCoordinates!!.size.height * scale).toInt(),
density = targetDensity,
content = content
)
}
}
}
Box(
modifier = Modifier
.onGloballyPositioned { actualLayoutCoordinates ->
layoutCoordinates = actualLayoutCoordinates
}
) {
content()
}
}