KotlinRay/src/main/kotlin/Bitmap.kt

57 lines
1.7 KiB
Kotlin
Raw Normal View History

2023-01-18 22:14:14 +01:00
import java.io.File
import java.io.OutputStream
const val BYTES_PER_PIXEL = 4
data class Color(val r: UByte, val g: UByte, val b: UByte, val alpha: UByte = UByte.MAX_VALUE)
2024-12-01 12:16:58 +01:00
@OptIn(ExperimentalUnsignedTypes::class)
2023-01-18 22:14:14 +01:00
class Bitmap(val width: Int, val height: Int) {
val data = UByteArray(width * height * BYTES_PER_PIXEL)
fun setPixel(x: Int, y: Int, color: Color) {
val offset = (y * width + x) * BYTES_PER_PIXEL
data[offset + 1] = color.g
data[offset + 0] = color.b
data[offset + 2] = color.r
data[offset + 3] = color.alpha
}
fun getPixel(x: Int, y: Int): Color {
val offset = (y * width + x) * BYTES_PER_PIXEL
return Color(
r = data[offset + 2],
g = data[offset + 1],
b = data[offset + 0],
alpha = data[offset + 3]
)
}
}
2024-12-01 12:16:58 +01:00
@OptIn(ExperimentalUnsignedTypes::class)
2023-01-18 22:14:14 +01:00
fun File.writeBitmap(bitmap: Bitmap) {
outputStream().use { stream ->
stream.write(0) // ID length
stream.write(0) // No color map
stream.write(2) // Uncompressed true color image
stream.writeWord(0) // Color map starts at index 0
stream.writeWord(0) // No color map entries
stream.write(0) // 0 bits per color map entry
stream.writeWord(0) // X origin
stream.writeWord(0) // Y origin
stream.writeWord(bitmap.width.toShort())
stream.writeWord(bitmap.height.toShort())
stream.write(BYTES_PER_PIXEL * 8)
stream.write(8)
stream.write(bitmap.data.toByteArray())
}
}
fun OutputStream.writeWord(word: Short) {
write(word.toInt() and 0xFF)
write((word.toInt() shr 8) and 0xFF)
}