Ok, just to try and strip this down to the actual problem, it's this?
let g2 = Graphics.createArrayBuffer(g.getWidth() * 2, g.getHeight(), 8, {msb:true});
let g2img = { width:g2.getWidth(), height:g2.getHeight(), bpp:8, buffer:g2.buffer };
g.reset().setBgColor("#0f0").clear();
// Screen is GREEN
let screengrab = g.asImage();
// Draw to offscreen buffer and back to screen
g2.drawImage(screengrab, 0, 0);
g.drawImage(g2img, 0, 0);
// Screen is BLUE
The issue is that when drawing a 3bpp image onto a 8bpp image, Espruino doesn't really know what to do about mapping colours - so it just copies the numeric color value straight across.
As @halemmerich noted, the best method is really to try and use a 4bpp graphics (which saves a bunch of memory over 8bpp), and to then explicitly tell Espruino what color palette to use for it (because normally for 4bpp it uses the Mac color palette).
His code works great, but you can also use toColor to avoid the cryptic constants:
let g2 = Graphics.createArrayBuffer(g.getWidth() * 2, g.getHeight(), 4, {msb:true});
let g2img = {
width:g2.getWidth(),
height:g2.getHeight(),
bpp:4,
buffer:g2.buffer,
palette : new Uint16Array([
g.toColor("#000"),
g.toColor("#00f"),
g.toColor("#0f0"),
g.toColor("#0ff"),
g.toColor("#f00"),
g.toColor("#f0f"),
g.toColor("#ff0"),
g.toColor("#fff"),
0,0,0,0,0,0,0,0,
])};
g.reset().setBgColor("#0f0").clear();
// Screen is GREEN
let screengrab = g.asImage();
// Draw to offscreen buffer and back to screen
g2.drawImage(screengrab, 0, 0);
g.drawImage(g2img, 0, 0);
// Screen is GREEN still
I've just added some color mappings from 3->4 and 3->8 bit into the Espruino firmware, and this should fix your original code on 8 bit, and will work on 4 bit too
... but then it'll fail on older firmwares. If you use my or @halemmerich's code then at least it'll be backwards compatible.
It's also worth adding that g2.setColor(colormap["#f00"]) isn't needed. g2.setColor("#f00") should work just fine - it'll search the color palette to find the closest matching color
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
Ok, just to try and strip this down to the actual problem, it's this?
The issue is that when drawing a 3bpp image onto a 8bpp image, Espruino doesn't really know what to do about mapping colours - so it just copies the numeric color value straight across.
As @halemmerich noted, the best method is really to try and use a 4bpp graphics (which saves a bunch of memory over 8bpp), and to then explicitly tell Espruino what color palette to use for it (because normally for 4bpp it uses the Mac color palette).
His code works great, but you can also use
toColor
to avoid the cryptic constants:I've just added some color mappings from 3->4 and 3->8 bit into the Espruino firmware, and this should fix your original code on 8 bit, and will work on 4 bit too
... but then it'll fail on older firmwares. If you use my or @halemmerich's code then at least it'll be backwards compatible.
It's also worth adding that
g2.setColor(colormap["#f00"])
isn't needed.g2.setColor("#f00")
should work just fine - it'll search the color palette to find the closest matching color