• 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

About

Avatar for Gordon @Gordon started