89 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
// Bodmers BMP image rendering function
 | 
						|
 | 
						|
void drawBmp(const char *filename, int16_t x, int16_t y) {
 | 
						|
 | 
						|
  if ((x >= tft.width()) || (y >= tft.height())) return;
 | 
						|
 | 
						|
  fs::File bmpFS;
 | 
						|
 | 
						|
  // Open requested file on SD card
 | 
						|
  bmpFS = SPIFFS.open(filename, "r");
 | 
						|
 | 
						|
  if (!bmpFS)
 | 
						|
  {
 | 
						|
    Serial.print("File not found");
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  uint32_t seekOffset;
 | 
						|
  uint16_t w, h, row, col;
 | 
						|
  uint8_t  r, g, b;
 | 
						|
 | 
						|
  uint32_t startTime = millis();
 | 
						|
 | 
						|
  if (read16(bmpFS) == 0x4D42)
 | 
						|
  {
 | 
						|
    read32(bmpFS);
 | 
						|
    read32(bmpFS);
 | 
						|
    seekOffset = read32(bmpFS);
 | 
						|
    read32(bmpFS);
 | 
						|
    w = read32(bmpFS);
 | 
						|
    h = read32(bmpFS);
 | 
						|
 | 
						|
    if ((read16(bmpFS) == 1) && (read16(bmpFS) == 24) && (read32(bmpFS) == 0))
 | 
						|
    {
 | 
						|
      y += h - 1;
 | 
						|
 | 
						|
      tft.setSwapBytes(true);
 | 
						|
      bmpFS.seek(seekOffset);
 | 
						|
 | 
						|
      uint16_t padding = (4 - ((w * 3) & 3)) & 3;
 | 
						|
      uint8_t lineBuffer[w * 3 + padding];
 | 
						|
 | 
						|
      for (row = 0; row < h; row++) {
 | 
						|
        
 | 
						|
        bmpFS.read(lineBuffer, sizeof(lineBuffer));
 | 
						|
        uint8_t*  bptr = lineBuffer;
 | 
						|
        uint16_t* tptr = (uint16_t*)lineBuffer;
 | 
						|
        // Convert 24 to 16 bit colours
 | 
						|
        for (uint16_t col = 0; col < w; col++)
 | 
						|
        {
 | 
						|
          b = *bptr++;
 | 
						|
          g = *bptr++;
 | 
						|
          r = *bptr++;
 | 
						|
          *tptr++ = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
 | 
						|
        }
 | 
						|
 | 
						|
        // Push the pixel row to screen, pushImage will crop the line if needed
 | 
						|
        // y is decremented as the BMP image is drawn bottom up
 | 
						|
        tft.pushImage(x, y--, w, 1, (uint16_t*)lineBuffer);
 | 
						|
      }
 | 
						|
      Serial.print("Loaded in "); Serial.print(millis() - startTime);
 | 
						|
      Serial.println(" ms");
 | 
						|
    }
 | 
						|
    else Serial.println("BMP format not recognized.");
 | 
						|
  }
 | 
						|
  bmpFS.close();
 | 
						|
}
 | 
						|
 | 
						|
// These read 16- and 32-bit types from the SD card file.
 | 
						|
// BMP data is stored little-endian, Arduino is little-endian too.
 | 
						|
// May need to reverse subscript order if porting elsewhere.
 | 
						|
 | 
						|
uint16_t read16(fs::File &f) {
 | 
						|
  uint16_t result;
 | 
						|
  ((uint8_t *)&result)[0] = f.read(); // LSB
 | 
						|
  ((uint8_t *)&result)[1] = f.read(); // MSB
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t read32(fs::File &f) {
 | 
						|
  uint32_t result;
 | 
						|
  ((uint8_t *)&result)[0] = f.read(); // LSB
 | 
						|
  ((uint8_t *)&result)[1] = f.read();
 | 
						|
  ((uint8_t *)&result)[2] = f.read();
 | 
						|
  ((uint8_t *)&result)[3] = f.read(); // MSB
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 |