Inkplate 2 drawImage fails with BMP, color not displaying

Customer:

I’m using Inkplate 2 to fetch and display images from a server via HTTP requests like:

http://10.10.101.11:5100/get_display?mac=CC:7B:5C:BE:95:B0&type=Inkplate2

The server returns a BMP image that Inkplate should display. I tried drawBitmapFromWeb with only black/white working and no red. Since drawBitmapFromWeb is deprecated, I switched to drawImage:

bool downloadAndDisplayBMP(const String& url, const String& dataHash) {
  Serial.print("BMP Download URL: ");
  Serial.println(url);
  Serial.printf("Data Hash: %s\n", dataHash.c_str());
  display.clearDisplay();
  HTTPClient http;
  http.getStream().setNoDelay(true);
  http.getStream().setTimeout(1);
  http.begin(url.c_str());
  int httpCode = http.GET();
  if (httpCode == 200) {
    Serial.println("HTTP 200 OK");
    int32_t len = http.getSize();
    Serial.printf("Content length: %d bytes\n", len);
    if (len > 0) {
      uint8_t *bmpBuffer = new uint8_t[len];
      if (!bmpBuffer) {
        Serial.println("Failed to allocate memory for BMP data");
        display.println("Memory error");
        display.display();
        http.end();
        return false;
      }
      WiFiClient *stream = http.getStreamPtr();
      size_t bytesRead = stream->readBytes(bmpBuffer, len);
      if (bytesRead != len) {
        Serial.println("Failed to read all bytes from stream");
        display.println("Download error");
        display.display();
        http.end();
        delete[] bmpBuffer;
        return false;
      }
      if (!display.drawImage(bmpBuffer, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0x00, 0xFF)) {
        Serial.println("display.drawImage() FAILED");
        display.println("Image draw error");
        display.display();
        http.end();
        delete[] bmpBuffer;
        return false;
      }
      Serial.println("display.drawImage() SUCCESS");
      display.display();
      http.end();
      delete[] bmpBuffer;
      dataHash.toCharArray(rtcState.dataHash, MAX_HASH_LEN);
      rtcState.lastRefreshTimestamp = time(nullptr);
      Serial.printf("Hash saved successfully: %s\n", rtcState.dataHash);
      Serial.printf("Refresh timestamp saved: %ld\n", rtcState.lastRefreshTimestamp);
      return true;
    }
  }
  return false;
}

The result is corrupted/garbled display output. I’ve spent the day on this. The server and OTA handling work fine. What am I missing? If I need to restructure the BMPs, use multiple files, or switch to PNG/JPG, I’m willing to try anything.

Attachment omitted in migration: image.png

Attachment omitted in migration: get_display-2.bmp

Attachment omitted in migration: get_display-3.bmp

Originally submitted via email support on 22 May 2025. Migrated to the forum for community visibility.

Soldered Support:

BMP has issues on Inkplate 2 - please switch to JPEG instead. This is a known issue in the library that we’re investigating.

A test with your image converted to JPG worked fine on Inkplate 2, including colors.

You can use drawImage with your local network source. If that doesn’t work, here’s a tested example that fetches a JPEG from your server and displays it:

#include "HTTPClient.h"
#include "Inkplate.h"
#include "WiFi.h"

Inkplate display;

const char* ssid = "Soldered-testingPurposes";
const char* password = "Testing443";
const char* imageUrl = "http://192.168.74.90:8000/test.jpg";

void setup() {
  Serial.begin(115200);
  display.begin();
  display.clearDisplay();
  Serial.print("Connecting to WiFi");
  WiFi.mode(WIFI_MODE_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi connected. Downloading image...");

  HTTPClient http;
  http.begin(imageUrl);
  int httpCode = http.GET();

  if (httpCode == HTTP_CODE_OK) {
    int32_t totalSize = http.getSize();
    int32_t remaining = totalSize;

    if (totalSize > 0) {
      uint8_t* buffer = (uint8_t*)ps_malloc(totalSize);
      uint8_t* ptr = buffer;
      uint8_t chunk[512];
      WiFiClient* stream = http.getStreamPtr();

      while (http.connected() && (remaining > 0 || totalSize == -1)) {
        size_t avail = stream->available();
        if (avail) {
          int len = stream->readBytes(chunk, min(avail, sizeof(chunk)));
          memcpy(ptr, chunk, len);
          if (remaining > 0) remaining -= len;
          ptr += len;
        } else if (totalSize == -1) {
          remaining = 0;
        }
      }

      display.drawJpegFromBuffer(buffer, totalSize, 0, 0, true, false);
      free(buffer);
    }
  }

  display.display();
}

void loop() {
}

Attachment omitted in migration: image.png