Created
December 23, 2023 19:03
-
-
Save cmelchior/5ebf2ed8c29b96b956d532ea2dd64eb5 to your computer and use it in GitHub Desktop.
Show how to capture a snapshot from a screen built using Compose inside Kotlin Notebooks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// JVM dependencies in build.gradle | |
val jvmMain by getting { | |
dependencies { | |
implementation(compose.desktop.currentOs) | |
implementation("org.jetbrains.skiko:skiko-awt-runtime-macos-arm64:+") | |
api(compose.preview) | |
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) | |
implementation(compose.desktop.uiTestJUnit4) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package dk.ilios.jervis.ui | |
import androidx.compose.foundation.background | |
import androidx.compose.foundation.layout.Box | |
import androidx.compose.foundation.layout.fillMaxSize | |
import androidx.compose.foundation.layout.padding | |
import androidx.compose.material.Text | |
import androidx.compose.runtime.Composable | |
import androidx.compose.ui.Alignment | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.graphics.Color | |
import androidx.compose.ui.graphics.asSkiaBitmap | |
import androidx.compose.ui.test.ExperimentalTestApi | |
import androidx.compose.ui.test.runDesktopComposeUiTest | |
import androidx.compose.ui.text.font.FontWeight | |
import androidx.compose.ui.unit.dp | |
import org.jetbrains.skia.Bitmap | |
import org.jetbrains.skia.Data | |
import org.jetbrains.skia.EncodedImageFormat | |
import org.jetbrains.skiko.toBufferedImage | |
import org.jetbrains.skiko.toImage | |
import java.awt.image.BufferedImage | |
import java.io.File | |
@Composable | |
fun Test(message: String) { | |
Box( | |
modifier = Modifier.background(color = Color.Gray).fillMaxSize().padding(16.dp), | |
contentAlignment = Alignment.Center | |
) { | |
Text(text = message, fontWeight = FontWeight.Thin, color = Color.White) | |
} | |
} | |
/** | |
* Easy entry point for taking snapshots that can be used by Kotlin Notebooks. | |
* This code must live inside a normal Gradle module, and can not be written | |
* directly inside the Notebook. | |
*/ | |
object Imager { | |
/** | |
* Take a screenshot of a specific screen. | |
*/ | |
fun testScreenshot(message: String, width: Int, height: Int): BufferedImage { | |
return renderScreenshot(width, height) { | |
Test(message) | |
} | |
} | |
/** | |
* Generic render function. Unfortunately it does not look it is possible to use | |
* Composables directly from Kotlin Notebook, so instead we need to add a helper | |
* method for each use case. | |
*/ | |
@OptIn(ExperimentalTestApi::class) | |
fun renderScreenshot(width: Int, height: Int, renderView: @Composable () -> Unit): BufferedImage { | |
lateinit var image: BufferedImage | |
runDesktopComposeUiTest(width, height) { | |
setContent { | |
renderView() | |
} | |
val screenshot: Bitmap = this.captureToImage().asSkiaBitmap() | |
image = screenshot.toBufferedImage() | |
} | |
return image | |
} | |
/** | |
* Optionally save the screenshot to a file | |
*/ | |
fun saveScreenshot(image: BufferedImage, name: String): File { | |
val file = File.createTempFile(name, ".png") | |
val img: Data? = image.toImage().encodeToData(EncodedImageFormat.PNG) | |
file.outputStream().use { stream -> | |
stream.write(img!!.bytes) | |
} | |
return file | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment