JPEG has 0 x 0 size. Skipping display

Hi all.
the code attached try to use ESP32 AP server receive image from phone or pc failed.
thanks for help to fix.

#include <WiFi.h>
#include <WebServer.h>
#include <SPIFFS.h>
#include <TJpg_Decoder.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();
WebServer server(80);

const char* ssid = "TTGO_HOTSPOT";
const char* password = "12345678";

// HTML Upload Form
const char uploadForm[] PROGMEM = R"rawliteral(
<!DOCTYPE html><html><head><title>Upload JPEG</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>body{font-family:sans-serif;font-size:20px;margin:2em;}</style></head>
<body><h2>Upload JPEG to TTGO</h2>
<form method="POST" action="/upload" enctype="multipart/form-data">
  <input type="file" name="upload" accept="image/jpeg"><br><br>
  <input type="submit" value="Upload">
</form></body></html>
)rawliteral";

// Draw callback
///bool tft_output(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t* bitmap) {

bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap) {
  Serial.printf("šŸ“¦ Drawing block: x=%d y=%d w=%d h=%d\n", x, y, w, h);
  if (y >= tft.height()) return false;
  tft.pushImage(x, y, w, h, bitmap);
  return true;
}

// Serve upload form
void handleUploadForm() {
  server.send_P(200, "text/html", uploadForm);
}

// Handle JPEG file upload
void handleUploadFile() {
  HTTPUpload& upload = server.upload();
  static File fsUploadFile;

  if (upload.status == UPLOAD_FILE_START) {
    fsUploadFile = SPIFFS.open("/uploaded.jpg", FILE_WRITE);
    Serial.printf("Upload started: %s\n", upload.filename.c_str());
  } else if (upload.status == UPLOAD_FILE_WRITE) {
    if (fsUploadFile) fsUploadFile.write(upload.buf, upload.currentSize);
  } else if (upload.status == UPLOAD_FILE_END) {
    if (fsUploadFile) {
      fsUploadFile.close();
      Serial.println("āœ… Upload complete!");
      File f = SPIFFS.open("/uploaded.jpg");
      if (!f || f.isDirectory()) {
        Serial.println("āŒ Failed to open uploaded.jpg after write");
        return;
      }
      Serial.printf("File size: %d bytes\n", f.size());
      uint8_t header[10]; f.read(header, 10);
      Serial.print("Header: ");
      for (int i = 0; i < 10; i++) Serial.printf("%02X ", header[i]);
      Serial.println();
      f.close();

      // Fill screen red to confirm it's working
      tft.fillScreen(TFT_RED);
      delay(1000);

      // Try to get JPEG size
      uint16_t w = 0, h = 0;


if (TJpgDec.getFsJpgSize(&w, &h, "/uploaded.jpg", SPIFFS)) {
  Serial.printf("āœ… JPEG size: %d x %d\n", w, h);
  if (w > 0 && h > 0) {
    tft.fillScreen(TFT_BLACK);
    TJpgDec.drawFsJpg(0, 0, "/uploaded.jpg", SPIFFS);
    Serial.println("āœ… Image decoded and displayed!");
  } else {
    Serial.println("āŒ JPEG has 0 x 0 size. Skipping display.");
    tft.fillScreen(TFT_RED);
    tft.setCursor(10, 10);
    tft.setTextColor(TFT_WHITE, TFT_RED);
    tft.println("Bad JPEG size");
  }
} else {
  Serial.println("āŒ Failed to get JPEG size — corrupt or unsupported?");
  tft.fillScreen(TFT_RED);
  tft.setCursor(10, 10);
  tft.setTextColor(TFT_WHITE, TFT_RED);
  tft.println("Unsupported JPEG");
}

      
/*      if (TJpgDec.getFsJpgSize(&w, &h, "/uploaded.jpg", SPIFFS)) {
        Serial.printf("āœ… JPEG size: %d x %d\n", w, h);
        tft.fillScreen(TFT_BLACK);
        TJpgDec.drawFsJpg(0, 0, "/uploaded.jpg", SPIFFS);
        Serial.println("āœ… Image decoded and displayed!");
      } else {
        Serial.println("āŒ Failed to get JPEG size — corrupt or unsupported?");
        tft.fillScreen(TFT_BLACK);
        tft.setCursor(10, 10);
        tft.setTextColor(TFT_RED);
        tft.println("Invalid JPEG");
      }  */
    }
  }
}

void setup() {
  Serial.begin(115200);
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.drawString("Starting AP...", 10, 10);

  WiFi.softAP(ssid, password);
  delay(1000);
  Serial.printf("\nšŸ“¶ AP IP address: %s\n", WiFi.softAPIP().toString().c_str());
  tft.drawString(WiFi.softAPIP().toString(), 10, 30);

  if (!SPIFFS.begin(true)) {
    Serial.println("āŒ SPIFFS mount failed");
    tft.drawString("SPIFFS mount failed", 10, 50);
    return;
  }

TJpgDec.setSwapBytes(true);
  TJpgDec.setCallback(tft_output);

  server.on("/", HTTP_GET, handleUploadForm);
  server.on("/upload", HTTP_POST, []() {
    server.send(200, "text/html", "<p>āœ… Upload complete!<br><a href='/'>Back</a></p>");
  }, handleUploadFile);

  server.begin();
  Serial.println("🌐 Web server started");
  tft.drawString("Server Ready", 10, 50);
}

void loop() {
  server.handleClient();
}

log:

šŸ“¶ AP IP address: 192.168.4.1
🌐 Web server started
Upload started: IMG_20250708_122758_701.jpg
āœ… Upload complete!
File size: 6756 bytes
Header: FF D8 FF DB 00 43 00 08 06 06 
āœ… JPEG size: 0 x 0
āŒ JPEG has 0 x 0 size. Skipping display.

Huge bit of code …..no idea how it works or where it finds a picture from your phone ?

As a general Point :

you should cut it down and get small chunks of it working , add print statements to check variables are doing what you think , then move on - it helps find out what is wrong.

Did you write this , copied usually often has issues or was intended for a different processor etc .

1 Like

Searching the above... led to the following...

Unknown if your issue is there.

1 Like

thanks.
I'll check there.

thanks.
ESP32 setup AP web server with name: TTGO_HOTSPOT, and IP: 192.168.4.1; phone login AP and upload image from phone, and all working. problem now is the: :cross_mark: JPEG has 0 x 0 size. Skipping display.