JetBrains / skija

Java bindings for Skia
Apache License 2.0
2.63k stars 127 forks source link

How can I convert Skija Image to BufferedImage? #137

Closed igr closed 2 years ago

tonsky commented 2 years ago

Both Bitmap and Image have peekPixels https://github.com/HumbleUI/Skija/blob/4620befb3b4e0a68e721138991ea658252e372f5/shared/java/Bitmap.java#L907-L923 which returns ByteBuffer with raw pixel colors. Is it enough to construct BufferedImage?

Example of using peekPixels could be found here https://github.com/HumbleUI/Skija/blob/4620befb3b4e0a68e721138991ea658252e372f5/examples/scenes/src/BitmapImageScene.java#L86-L93

I think Skiko has an example of using it for software rendering https://github.com/JetBrains/skiko/blob/3facce459be7d7445d8da419a544a2bafd3e69f1/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/SoftwareContextHandler.kt#L61-L87

igr commented 2 years ago

fun Image.toBufferedImage(): BufferedImage {
    val storage = Bitmap()
    storage.allocPixelsFlags(ImageInfo.makeS32(this.width, this.height, ColorAlphaType.PREMUL), false)
    Canvas(storage).drawImage(this, 0f, 0f)

    val bytes = storage.readPixels(storage.imageInfo, (this.width * 4L), 0, 0)!!
    val buffer = DataBufferByte(bytes, bytes.size)
    val raster = Raster.createInterleavedRaster(
        buffer,
        this.width,
        this.height,
        this.width * 4, 4,
        intArrayOf(2, 1, 0, 3),     // BGRA order
        null
    )
    val colorModel = ComponentColorModel(
        ColorSpace.getInstance(ColorSpace.CS_sRGB),
        true,
        false,
        Transparency.TRANSLUCENT,
        DataBuffer.TYPE_BYTE
    )

    return BufferedImage(colorModel, raster!!, false, null)
}```