Adafruit GFX drawBitmap change the way it works

I am using a Sharp Memory Display by Adafruit, and I create an image in a canvas buffer. On a colour TFT this works awesome, but not on B&W screens like the Memory Display. I believe the issue comes from the way drawBitmap from Adafruit GFX differs from drawRGBbitmap.
The RGB version just copies all bytes from buffer to display.
The B&W version has an additional input: the desired colour. What it does is it copies only 1's to the display as either 0 or 1 depending on the colour variable (COLOUR). I want it to copy both 0's and 1's unaltered, so that both white and black pixels get updated.

// this is how it works now in RGB:
tft.drawRGBBitmap(400,240,canvas.getBuffer(),240,240);
// this is how it works half-baked in B&W (only 1's are copied).
tft.drawBitmap(400,240,canvas.getBuffer(),400,240,COLOUR);

// this is how I need it to work:
tft.drawBitmap(400,240,canvas.getBuffer(),400,240);

How can I achieve this?

  void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h,
                  uint16_t color, uint16_t bg);

Use e.g. 0x0000 (black) for color, 0xFFFF (white) for bg (background), or vice-versa.

The thing is I want to write both black and white at the same time, basically copying the raw 0's and 1's from the buffert to the display. You can't use the function to draw the 0's.

Are you sure? That's what the method with bg parameter is for, afaik.
Use 0xFFFF for color, 0x0000 for bg, else it will be inverted, I think.
But I usually use the other way, for black on white for e-paper displays.

/**************************************************************************/
/*!
   @brief      Draw a RAM-resident 1-bit image at the specified (x,y) position,
   using the specified foreground (for set bits) and background (unset bits)
   colors.
    @param    x   Top left corner x coordinate
    @param    y   Top left corner y coordinate
    @param    bitmap  byte array with monochrome bitmap
    @param    w   Width of bitmap in pixels
    @param    h   Height of bitmap in pixels
    @param    color 16-bit 5-6-5 Color to draw pixels with
    @param    bg 16-bit 5-6-5 Color to draw background with
*/
/**************************************************************************/
void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w,
                              int16_t h, uint16_t color, uint16_t bg) {

  int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
  uint8_t b = 0;

  startWrite();
  for (int16_t j = 0; j < h; j++, y++) {
    for (int16_t i = 0; i < w; i++) {
      if (i & 7)
        b <<= 1;
      else
        b = bitmap[j * byteWidth + i / 8];
      writePixel(x + i, y, (b & 0x80) ? color : bg);
    }
  }
  endWrite();
}

Thanks, that worked!

Found an even better solution. If you set the memory display buffer to public in the library, you can simply copy the whole buffer at once.

Can you share the code for that?

The library function getBuffer() will return a uint8_t* to the display buffer, no need to alter the library.

I found the drawBitmap function to be incredibly slow, so the memcopy is the way to go:
Step 1: modify the library.
Search your computer for Adafruit_SharpMem.h
Edit the file and move around line 55:
uint8_t *sharpmem_buffer = NULL;
a few lines up so it is under public: and no longer under private:

Now you can copy the canvas to the display memory with:
tft.sharpmem_buffer=canvas.getBuffer();
If you use another name for the display object than tft then change accordingly.

Strange, I got an error when I tried without modifying.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.