Kotlin неподписанных байтов с JavaScript Uint8ClampedArray
У меня есть программа, которая пытается установить значения в ImageData, представленные как Uint8ClampedArray в программе Kotlin. В соответствии со спецификацией для метода set мне нужно передать байт Kotlin в массив, но байты Kotlin подписаны:
...create context...
//setup pix as a js Uint8ClampedArray
val imgd = context.createImageData(100.0, 100.0)
val pix = imgd.data //pix is now a Uint8ClampedArray
//sets pix[40] to 127
pix[40] = 127
//gives an error - Kotlin bytes are signed, so it cannot be passed as a literal
pix[40] = 200
//also doesn't work, still converts to a signed byte
pix[40] = 200.toByte()
Моя проблема с этим заключается в том, что Javascript будет читать это как 127, а не 255. Как я могу установить значения этого массива больше 127? Я даже не могу найти хакерский способ заставить результат JS читать то, что я хочу, потому что в конечном итоге для присваивания требуется подписанный байт, который не допускает значений, превышающих 127.
1 ответ
Я понял! Вы можете выполнить небезопасное приведение массива UInt8 к массиву UInt16, а затем использовать его вместо этого, и javascript, похоже, определит, что вы имеете в виду:
//instead of val pix = imgd.data
val pix = imgd.data.unsafeCast<Uint16Array>()
// now you can assign values outside the -127..127 range
Проблема с трекером Kotlin - https://youtrack.jetbrains.com/issue/KT-24583
org.khronos.webgl.Uint8ClampedArray getter и setter объявления используют Byte. Это означает, что присвоить ему значения более 127 нетривиально. Также полученные из него значения нарушают контракт байта
Кроме того, можно утверждать, что это не "настоящий" массив. Назначение значений вне диапазона 0..255 для него вполне нормально.
Этот случай важен, потому что он используется для манипуляции с холстом: https://developer.mozilla.org/en-US/docs/Web/API/ImageData/data