Help with TFT display and 8bit grayscale bitmap

Hi guys I'm working with 1.14 inch TFT display (240x135) and I want to display an 8-bit grayscale bitmap problem is that when it is displayed the image is half the size and slightly rotated tried couple of things but managed to only get so far with no idea what to do next. Also working with esp32 and onboard tft display.

this is what the display shows:

this is the code I'm using:

case 7:
      tft.setRotation(0);
      displaySyndra(syndra0, 135, 240, 0, 0);
      delay(100);
      break;
void displaySyndra(const unsigned char *syndra0, int width, int height, int x, int y) {
  for (int row = 0; row < height; row++) {
    for (int col = 0; col < width; col++) {
      int pixelIndex = (row * width + col) / 2; // Calculate pixel index
      int pixelValue = pgm_read_byte(syndra0 + pixelIndex); // Read pixel value from PROGMEM

      // Extract the 4-bit grayscale value
      int grayscale = (pixelValue >> ((col % 2) * 4)) & 0x0F;

      tft.drawPixel(x + col, y + row, tft.color565(grayscale * 16, grayscale * 16, grayscale * 16));
    }
  }
}

Any form of help appreciated.

Please post a link to the actual display, state which Arduino you are using, and post the complete code (not a snippet).

No problem here is the board with the display:

https://a.aliexpress.com/_EvTYNSL

And here is the full code

#include <minkoValekInfoCentrumBitmaps.h>
#include "driver/gpio.h"
#include <rom/ets_sys.h>
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
#include <SPI.h>

TFT_eSPI tft = TFT_eSPI();

#define TFT_BLACK   0x0000
#define TFT_GRAY    0x8410
#define TFT_WHITE   0xFFFF
#define TFT_RED     0xF800
#define TFT_ORANGE  0xFA60
#define TFT_YELLOW  0xFFE0  
#define TFT_LIME    0x07FF
#define TFT_GREEN   0x07E0
#define TFT_CYAN    0x07FF
#define TFT_AQUA    0x04FF
#define TFT_BLUE    0x001F
#define TFT_MAGENTA 0xF81F
#define TFT_PINK    0xF8FF

uint16_t TFT_MAIN = 0xFFFF;
uint16_t TFT_SEC = 0xF81F;
int mainMenuPosition = 1;

int x = 0;
int y = 0;
int size = 20;
uint16_t cursorColor = 0xF81F;
int lightState = 1;
bool case3Cleared = false;
bool isInSettings = false;


void setup() {
  //display setup
  tft.init();
  tft.setRotation(1);
  clearScreen();
  //button setup
  pinMode(0, INPUT_PULLUP);
  pinMode(35, INPUT_PULLUP);
  //startup screen
  //loadingScreen();
  //setup code
  mainMenuScreen();
  osName();
}

void loop() {
  if(digitalRead(0) == 0  && isInSettings == false) {
    switch(mainMenuPosition) {
      case 1:
      mainMenuScreen();
      positionOne(29, 22, 30, cursorColor);
      mainMenuPosition = 2;
      osName();
      delay(100);
      break;
      case 2:
      mainMenuScreen();
      positionOne(71, 22, 30, cursorColor);
      mainMenuPosition = 3;
      osName();
      delay(100);
      break;
      case 3:
      mainMenuScreen();
      positionOne(108, 22, 30, cursorColor);
      mainMenuPosition = 4;
      osName();
      delay(100);
      break;
      case 4:
      mainMenuScreen();
      positionOne(148, 22, 30, cursorColor);
      mainMenuPosition = 5;
      osName();
      delay(100);
      break;
      case 5:
      mainMenuScreen();
      positionOne(188, 22, 30, cursorColor);
      mainMenuPosition = 6;
      osName();
      delay(100);
      break;
      case 6:
      mainMenuScreen();
      positionOne(27, 90, 30, cursorColor);
      mainMenuPosition = 7;
      osName();
      delay(100);
      break;
      case 7:
      mainMenuScreen();
      positionOne(68, 90, 30, cursorColor);
      mainMenuPosition = 8;
      osName();
      delay(100);
      break;
      case 8:
      mainMenuScreen();
      positionOne(108, 90, 30, cursorColor);
      mainMenuPosition = 9;
      osName();
      delay(100);
      break;
      case 9:
      mainMenuScreen();
      positionOne(150, 88, 30, cursorColor);
      mainMenuPosition = 10;
      osName();
      delay(100);
      break;
      case 10:
      mainMenuScreen();
      positionOne(185, 88, 30, cursorColor);
      mainMenuPosition = 11;
      osName();
      delay(100);
      break;
      case 11:
      mainMenuScreen();
      mainMenuPosition = 1;
      osName();
      delay(100);
      break;

      default:
      mainMenuScreen();
      delay(10);
      break;
    }
  }

  if(digitalRead(35) == 0) {
    switch(mainMenuPosition) {
      case 2:
      
        switch(lightState) {
        case 1:
        TFT_MAIN = 0xF81F;
        cursorColor = 0xFFFF;
        lightState = 2;
        delay(100);
       break;
        case 2:
        TFT_MAIN = 0xFFFF;
       cursorColor = 0x0000;
       lightState = 1;
       delay(100);
       break;
       }

      mainMenuScreen();
      delay(200);
      break;
      
      case 3:

      if (case3Cleared == false ) {
      clearScreenW();
      printSettings();
      isInSettings = true;
        
        if(digitalRead(0) == 0  && isInSettings == true){
          tft.println("JAKOOOOO");
          case3Cleared = true;
          delay(200);
        }
      }
      


      delay(200);
      break;

      case 4:

      break;
      
      case 5:

      break;

      case 6:

      break;

      case 7:
      tft.setRotation(0);
      displaySyndra(syndra0, 135, 240, 0, 0);
      delay(100);
      break;

      case 8:

      break;

      case 9:

      break;

      case 10:

      break;

      case 11:
      tft.fillScreen(TFT_BLACK);
      delay(100);
      break;
      default:
      delay(10);
      break;
    }
  }
}

void clearScreen() {
  tft.fillScreen(TFT_BLACK);
}

void clearScreenW() {
  tft.fillScreen(TFT_WHITE);
}

void mainMenuScreen() {
  tft.drawBitmap(0,0,mainmenu, 240, 135, TFT_MAIN);
}

void printSettings() {
  tft.println("Exit:");
}

void loadingScreen() {
  tft.drawBitmap(0,0,startupLogo, 240, 135, TFT_MAIN);
  delay(2000);
  clearScreen();
  tft.drawBitmap(0,0,loading0, 240, 135, TFT_MAIN);
  delay(1000);
  clearScreen();
  tft.drawBitmap(0,0,loading1, 240, 135, TFT_MAIN);
  delay(500);
  clearScreen();
  tft.drawBitmap(0,0,loading2, 240, 135, TFT_MAIN);
  delay(250);
  clearScreen();
  tft.drawBitmap(0,0,loading3, 240, 135, TFT_MAIN);
  delay(500);
  clearScreen();
  tft.drawBitmap(0,0,loading4, 240, 135, TFT_MAIN);
  delay(1000);
  clearScreen();
  tft.drawBitmap(0,0,loading5, 240, 135, TFT_MAIN);
  delay(250);
  clearScreen();
  tft.drawBitmap(0,0,loading6, 240, 135, TFT_MAIN);
  delay(1500);
  clearScreen();
  tft.drawBitmap(0,0,loading7, 240, 135, TFT_MAIN);
  delay(500);
  clearScreen();
}


void displaySyndra(const unsigned char *syndra0, int width, int height, int x, int y) {
  for (int row = 0; row < height; row++) {
    for (int col = 0; col < width; col++) {
      int pixelIndex = (row * width + col) / 2; // Calculate pixel index
      int pixelValue = pgm_read_byte(syndra0 + pixelIndex); // Read pixel value from PROGMEM

      // Extract the 4-bit grayscale value
      int grayscale = (pixelValue >> ((col % 2) * 4)) & 0x0F;

      tft.drawPixel(x + col, y + row, tft.color565(grayscale * 16, grayscale * 16, grayscale * 16));
    }
  }
}


void osName() {
  tft. setTextColor(TFT_BLACK);
  tft.setCursor(95, 0, 2);
  tft.println("Pavlii OS");
}

void positionOne(int x, int y, int size, uint16_t cursorColor) {
  // Top and bottom lines
  tft.drawLine(x, y, x + size - 1, y, cursorColor);
  tft.drawLine(x, y + size - 1, x + size - 1, y + size - 1, cursorColor);

  // Left and right lines
  tft.drawLine(x, y, x, y + size - 1, cursorColor);
  tft.drawLine(x + size - 1, y, x + size - 1, y + size - 1, cursorColor);
}

some parts of the code are not finished.

what is inside minkoValekInfoCentrumBitmaps.h ?

Hi thanks for asking the file contains all of my bitmaps here is it if anyone can help lol :sob:
minkoValekInfoCentrumBitmaps.h (24.3 KB)

I am just dumb for anyone wondering I just now realised I mentioned my own library inside my own library now it works as expected :smile:

Hi Martynzys,

What are the dimensions of the bitmap (height, width), in pixels ?
regards, Photoncatcher

hi Martynezys,

The solution is very simple: the dimensions of your logo are 240x135.
Here is the sketch that works with TFT_eSPI as library, and a picture how the logo looks like in my sketch

success, Photoncatcher

Minko_startupLogo_sketch.zip (3.11 KB)