-
• #2
Okay, some updates.
I made it. The issue was I had to define a palette myself. I falsely assumed there was one already existing.
However there seems to be still an issue.
I defined this:
var pal = new Uint16Array([ 0x0000, //0000000000000000 BLACK 0xF800, //1111100000000000 5 bit RED 0x07E0, //0000011111100000 6 bits GREEN 0x001F, //0000000000011111 5 bit BLUE 0x0000, //0000000000000000 BLACK 0xF800, //1111100000000000 5 bit RED 0x07E0, //0000011111100000 6 bits GREEN 0x001F, //0000000000011111 5 bit BLUE ]); var colors = new Uint8Array([ 0b00110011, 0b00110010, 0b00110011, 0b00110010, 0b00110011, 0b00110010, 0b00110011, 0b00110010, ]); var img = { width : 4, height : 4, bpp : 4, palette:pal, buffer : colors.buffer }; g.drawImage(img, 10, 10)
But the error I get goes as follows:
Uncaught Error: Palette specified, but must be a flat Uint16Array of 2,4,8,16,256 elements
at line 1 col 24But I have 8 elements there. If I chose 2, 4 or 16 everything works fine. So is this a bug? Am I missing something? Why would it tell me 8 colors are fine when they are obviously not?
-
• #3
The constructor for those arrays doens't bother trying to create a flatstring if the length of array is small, I tested with length of 10 , and it did create a flatstring. So you have to find a way to force it / convert it to flatstring.
There are functions like E.toString, which try to return a flatstring. I don't know the absolute solution, but this should help point in right direction.
Oh and you can confirm its underlying type by using
trace(yourObject)
eg.trace(pal);
-
• #4
I fiddled with it and found a little tricky way to make it behave. Creating initial ArrayBufferView length 9, to ensure FlatString creation, then using
offset
to copy this to a new one.var pal = new Uint16Array( new Uint16Array([ 0, 0x0000, //0000000000000000 BLACK 0xF800, //1111100000000000 5 bit RED 0x07E0, //0000011111100000 6 bits GREEN 0x001F, //0000000000011111 5 bit BLUE 0x0000, //0000000000000000 BLACK 0xF800, //1111100000000000 5 bit RED 0x07E0, //0000011111100000 6 bits GREEN 0x001F, //0000000000011111 5 bit BLUE ]).buffer,1,8); trace(pal); var colors = new Uint8Array([ 0b00110011, 0b00110010, 0b00110011, 0b00110010, 0b00110011, 0b00110010, 0b00110011, 0b00110010, ]); var img = { width : 4, height : 4, bpp : 4, palette:pal, buffer : colors.buffer }; g.drawImage(img, 10, 10)
This works because when an ArrayBuffer is passed to the constructor, as opposed to an ArrayBufferView, the underlying buffer is referenced instead of copied.
Uint16Array is the
ArrayBufferView
, it views the data below it. -
• #5
Hi! I'll look into this - it might be a firmware issue.
On the Bangle.js 1, it's a 16 bit display and the Mac palette is honoured - however I believe on the 2 we might just pass the 4 bits right through. I'll check on that as it'd explain a lot of your issues.
For your
Palette specified, but must be a flat Uint16Array of 2,4,8,16,256 elements
error, it looks like you've asked for a 4 bit image which would require a 16 entry palette, but you only supplied an 8 entry one? I'd imagine that could be your problem -
• #6
Ok, I just did some testing here... Looks like Bangle.js 2 does do the right thing...
For instance:
var img = require("heatshrink").decompress(atob("plcwkDmYAP5gACCiAAOngkDAAPDEkYmeEg50cJQnBjhMeEonIxgleNYkYwJyeDwmIxFcEsPCEoJyEErsYEoOCErq9C4IkBAALlCcbpKCAAK/CErRyB4okDX4YkaJgIlHJTYABmAlFgYkcmcAEosAEv5wDgIlGOTgl/EuUA1AkDwIldDwJMEiAlaDwWJgAmBiMREgMAzALBwYjWAAOZ0AgBAAcKxINDE6E4EgmJzOKEoupzJMCAAQkTJQIAByIkDhIICCIpOLCIokDAAOaEgMRklEolCkQmPJIxvBIA0t7oAEpAmMEg5RGAAVNEonSJpgdJAA+NEonUBowkWxGEOQoNGJgZvGABmCJIa+GJgokSAAJuJJgwlVEhZMCOCYlClAOMwYlVpAONwYkUAH4ALzAkjxJK/JTk4EiOZCSGDEqOYxJxQwczN6QmQmczJhwhDOaAlBJhxGEJhwkCJhuZD4oGGSo4ADN5znFExQkEExQbJExQkGOg4ZBWpQMHNwoAGCgQACUJgADEZglGdpoSCzAkNEoYjNUwolOTIoAPOBwl8EhwlmmZwjEvYkQEsy+SOCIl/TD4kSEsxyREsiWTOSIl7OR4l7OR4kVEouZABAlWnAhJAAWRiYmWEpkcEq+JJRfMEq5yLjnMqYlWJhWl5nM4YlXJhAkC5nBEq5MHiokCAAKYXJguRrgkEJjeqiNVEYoACX7ExERAACrODMAoGFABaSFAAnFPgOYEAWIzBNSjglIjLKFEiYmJrQkFzKbWOgvBJLbCErgkIxAkYAAURiIiEEZAA=")) g.drawImage(img);
or
var img = { width : 76, height : 92, bpp : 4, transparent : 3, buffer : require("heatshrink").decompress(atob("mYAP5gACCiAAOngkDAAPDEkYmeEg50cJQnBjhMeEonIxgleNYkYwJyeDwmIxFcEsPCEoJyEErsYEoOCErq9C4IkBAALlCcbpKCAAK/CErRyB4okDX4YkaJgIlHJTYABmAlFgYkcmcAEosAEv5wDgIlGOTgl/EuUA1AkDwIldDwJMEiAlaDwWJgAmBiMREgMAzALBwYjWAAOZ0AgBAAcKxINDE6E4EgmJzOKEoupzJMCAAQkTJQIAByIkDhIICCIpOLCIokDAAOaEgMRklEolCkQmPJIxvBIA0t7oAEpAmMEg5RGAAVNEonSJpgdJAA+NEonUBowkWxGEOQoNGJgZvGABmCJIa+GJgokSAAJuJJgwlVEhZMCOCYlClAOMwYlVpAONwYkUAH4ALzAkjxJK/JTk4EiOZCSGDEqOYxJxQwczN6QmQmczJhwhDOaAlBJhxGEJhwkCJhuZD4oGGSo4ADN5znFExQkEExQbJExQkGOg4ZBWpQMHNwoAGCgQACUJgADEZglGdpoSCzAkNEoYjNUwolOTIoAPOBwl8EhwlmmZwjEvYkQEsy+SOCIl/TD4kSEsxyREsiWTOSIl7OR4l7OR4kVEouZABAlWnAhJAAWRiYmWEpkcEq+JJRfMEq5yLjnMqYlWJhWl5nM4YlXJhAkC5nBEq5MHiokCAAKYXJguRrgkEJjeqiNVEYoACX7ExERAACrODMAoGFABaSFAAnFPgOYEAWIzBNSjglIjLKFEiYmJrQkFzKbWOgvBJLbCErgkIxAkYAAURiIiEEZA")) }
Draws a blue genie - that's using 4bpp and no palette, which means the Mac palette is used.
If I take your original code and run it in a FOR loop (for all 16 colors) I get the attached image, which looks good to me.
g.clear(); for (var i=0;i<16;i++) { var colorPalette3 = new Uint8Array([ i<<4 ]); var img = { width : 1, height : 1, bpp : 4, buffer : colorPalette3.buffer }; g.drawImage(img, 10 + (i&3)*20, 10 + ((i>>2)&3)*20, {scale:20}) }
Worth noting that because images are MSB aligned and you have 8 bits but only one 4 bit pixel, the color data is in the top 4 bits.
1 Attachment
-
• #7
Thanks, I guess I gonna look into this a bit further.
Sorry for posting this twice. I'm not sure which board is the right one to ask something for my Bangle.js project. Please close the wrong one if needed (http://forum.espruino.com/conversations/373677/#comment16426952)
Hello everyone,
in my project for my Bangle.js I need to draw a picture from an Array.
Since it has to be performant - and the display isn't capable of many more colors - I was thinking of using the 4bit images.
The API
https://www.espruino.com/Reference#l_Graphics_drawImage
states
"On Bangle.js, 4 bit images use the Apple Mac 16 color palette"
However, I don't seem to understand how this palette is organized.
From what I understand when painting the image, defining the bpp to 4 enables this dirctly. And the values that are drawn are not color values (e.g. RGB) but values of a fixed color set. E.g. 0 = black, 1 = yellow or such kind)
So I made a minimal example code like this hoping to see some colors:
However this is almost all the time showing a black pixel. Some values lead to other colors but I can't understand the pattern. I also tried it with integer values hoping to understand the palette but without success.
Could anyone help me with that? Or maybe a like would be nice.
I even tried the color scheme I saw on Wikipedia where each bit suggests the color canal to be 1 or 0. But even then a 001 should not be black, right?
https://en.wikipedia.org/wiki/List_of_monochrome_and_RGB_color_formats#3-bit_RGB
Thanks for the help!