korlibs / korlibs/korlibs-image
Trying to implement BitmapSRGB so that it can take in bytes from Webcam without needing to convert to TYPE_INT_ARGB_PRE
- Dominant language
- Kotlin
- Stars
- 2
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
The image looks all wrong:
Can you please take a look at my implementation and see if I'm missing anything?
```
import korlibs.image.bitmap.Bitmap
import korlibs.image.color.RGBA
import kotlin.math.pow
class BitmapSRGB(
width: Int,
height: Int,
val data: ByteArray = ByteArray(width * height * 3),
): Bitmap(width, height, 8, true, data) {
override fun getInt(x: Int, y: Int): Int {
val idxStart = (x * 3) + (y * width * 3)
val r = data[idxStart].toInt()
val g = data[idxStart + 1].toInt()
val b = data[idxStart + 2].toInt()
val linearRgb = doubleArrayOf(r / 255.0, g / 255.0, b / 255.0)
// Linearization
for (i in 0..2) {
linearRgb[i] = if (linearRgb[i] <= 0.04045) {
linearRgb[i] / 12.92
} else {
((linearRgb[i] + 0.055) / 1.055).pow(2.4)
}
}
// sRGB to XYZ matrix transformation
val srgbToXyzMatrix = arrayOf(
doubleArrayOf(0.4124564, 0.3575761, 0.1804375),
doubleArrayOf(0.2126729, 0.7151522, 0.0721750),
doubleArrayOf(0.0193339, 0.1191920, 0.9503041)
)
val xyz = DoubleArray(3)
for (i in 0..2) {
for (j in 0..2) {
xyz[i] += srgbToXyzMatrix[i][j] * linearRgb[j]
}
}
// XYZ to Adobe RGB matrix transformation
val xyzToAdobeRgbMatrix = arrayOf(
doubleArrayOf(2.0413690, -0.5649464, -0.3446944),
doubleArrayOf(-0.9692660, 1.8760108, 0.0415560),
doubleArrayOf(0.0134474, -0.1183897, 1.0154096)
)
val linearAdobeRgb = DoubleArray(3)
for (i in 0..2) {
for (j in 0..2) {
linearAdobeRgb[i] += xyzToAdobeRgbMatrix[i][j] * xyz[j]
}
}
// Gamma correction
for (i in 0..2) {
linearAdobeRgb[i] = if (linearAdobeRgb[i] <= 0.0) {
0.0
} else {
linearAdobeRgb[i].pow(1 / 2.19921875)
}
}
// Convert back to integer bytes (0-255)
val adobeRgb = IntArray(3)
for (i in 0..2) {
adobeRgb[i] = (linearAdobeRgb[i] * 255.0).toInt()
}
// return RGBA(adobeRgb[0], adobeRgb[1], adobeRgb[2]).value
return (adobeRgb[0] shl 0) or (adobeRgb[1] shl 8) or (adobeRgb[2] shl 16) or (0xFF shl 24)
}
override fun setInt(x: Int, y: Int, color: Int) = TODO()
override fun getRgbaRaw(x: Int, y: Int): RGBA = RGBA(getInt(x, y))
}
```
**For context:** The webcam image is in terms of sRGB:
https://github.com/Kietyo/webcam-capture-kotlin/blob/master/src/main/kotlin/com/github/sarxos/webcam/ds/buildin/WebcamDefaultDevice.kt#L394
Resources I followed for my implementation:
- https://en.wikipedia.org/wiki/SRGB
- https://en.wikipedia.org/wiki/Adobe_RGB_color_space
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reviewing the BitmapSRGB implementation in the issue, especially its byte indexing, color conversion, channel packing, and unimplemented setInt method. Compare its assumptions with Bitmap and the webcam sRGB byte source linked in the report. Done means webcam bytes can be used directly and the resulting image displays with correct colors without conversion to TYPE_INT_ARGB_PRE.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- kotlin
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100