1  | void bmpDraw(String filename, int x, int y) {
 | 
2  | 
  | 
3  |   File     bmpFile;
  | 
4  |   int      bmpWidth, bmpHeight;          // W+H in Pixel
  | 
5  |   uint8_t  bmpDepth;                     // Bittiefe (muss derzeit 24 sein)
  | 
6  |   uint32_t bmpImageoffset;               // Beginn der Bilddaten in der Datei
  | 
7  |   uint32_t rowSize;                      // Nicht immer = bmpWidth; kann Füllung haben
  | 
8  |   uint8_t  sdbuffer[3 * BUFFPIXEL];      // Pixel im Puffer (R+G+B pro Pixel)
  | 
9  |   uint16_t lcdbuffer[BUFFPIXEL];         // Pixel-Ausgangspuffer (16-Bit pro Pixel)
  | 
10  |   uint8_t  buffidx = sizeof(sdbuffer);   // Aktuelle Position im sdbuffer
  | 
11  |   boolean  goodBmp = false;              // Bei gültigem Header-Parsing auf true setzen
  | 
12  |   boolean  flip = true;                  // BMP wird von unten nach oben gespeichert
  | 
13  |   int      w, h, row, col;
  | 
14  |   uint8_t  r, g, b;
  | 
15  |   uint32_t pos = 0;
  | 
16  |   uint8_t  lcdidx = 0;
  | 
17  |   boolean  first = true;
  | 
18  | 
  | 
19  |   if ((x >= 64) || (y >= 32)) return; // zu groß
  | 
20  | 
  | 
21  |   // Angeforderte Datei auf SD-Karte öffnen
  | 
22  |   if (!(bmpFile = SPIFFS.open(filename, "r"))) return; // keine Datei gefunden
  | 
23  | 
  | 
24  |   // Parse BMP header
  | 
25  |   if (read16(bmpFile) == 0x4D42) // BMP-Signatur
  | 
26  |   {
 | 
27  |    Serial.print(F("Dateigröße: ")); Serial.println(read32(bmpFile));
 | 
28  | 
  | 
29  |     read32(bmpFile);                  // Erzeuger-Bytes lesen & ignorieren
  | 
30  |     bmpImageoffset = read32(bmpFile); // Beginn der Bilddaten
  | 
31  | 
  | 
32  |    Serial.print(F("Headergröße: ")); Serial.println(read32(bmpFile));
 | 
33  | 
  | 
34  |     bmpWidth  = read32(bmpFile);
  | 
35  |     bmpHeight = read32(bmpFile);
  | 
36  |     if (read16(bmpFile) == 1) // # Ebenen -- muss '1' sein
  | 
37  |     {
 | 
38  |       bmpDepth = read16(bmpFile); //  Bits pro Pixel
  | 
39  |       Serial.print(F("Bittiefe: ")); Serial.println(bmpDepth);
 | 
40  | 
  | 
41  |       if ((bmpDepth == 24) && (read32(bmpFile) == 0)) // 0 = unkomprimiert
  | 
42  |       {
 | 
43  |         goodBmp = true; // Unterstütztes BMP-Format -- weiter!
  | 
44  | 
  | 
45  |         rowSize = (bmpWidth * 3 + 3) & ~3; 
  | 
46  | 
  | 
47  |         if (bmpHeight < 0) {
 | 
48  |           bmpHeight = -bmpHeight;
  | 
49  |           flip      = false;
  | 
50  |         }
  | 
51  | 
  | 
52  |         // Crop area to be loaded
  | 
53  |         w = bmpWidth;
  | 
54  |         h = bmpHeight;
  | 
55  |         if ((x + w - 1) >= 64)  w = 64  - x; // Breite
  | 
56  |         if ((y + h - 1) >= 32) h = 32 - y;   // Höhe
  | 
57  | 
  | 
58  |         for (row = 0; row < h; row++)
  | 
59  |         {
 | 
60  |           if (flip) 
  | 
61  |             pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
  | 
62  | 
  | 
63  |           else     // Bitmap wird von oben nach unten gespeichert
  | 
64  |             pos = bmpImageoffset + row * rowSize;
  | 
65  | 
  | 
66  |           if (bmpFile.position() != pos) { // suchen?
 | 
67  |             bmpFile.seek(pos);
  | 
68  |             buffidx = sizeof(sdbuffer); // Puffer-Neuladen erzwingen
  | 
69  |           }
  | 
70  | 
  | 
71  |           for (col = 0; col < w; col++) // Für jede Spalte...
  | 
72  |           {
 | 
73  | 
  | 
74  |             // Zeit, mehr Pixeldaten zu lesen?
  | 
75  |             if (buffidx >= sizeof(sdbuffer)) { // tatsächlich
 | 
76  | 
  | 
77  |               bmpFile.read(sdbuffer, sizeof(sdbuffer));
  | 
78  |               buffidx = 0; // Index auf Anfang setzen
  | 
79  |             }
  | 
80  | 
  | 
81  |             // Pixel von BMP in TFT-Format konvertieren
  | 
82  |             b = sdbuffer[buffidx++];
  | 
83  |             g = sdbuffer[buffidx++];
  | 
84  |             r = sdbuffer[buffidx++];
  | 
85  | 
  | 
86  |             display.drawPixelRGB888(col, row, r, g, b);
  | 
87  |           } // Endpixel
  | 
88  |         } // Scanline beenden
  | 
89  |       } 
  | 
90  |     }
  | 
91  |   }
  | 
92  | 
  | 
93  |   bmpFile.close();
  | 
94  |   if (!goodBmp) Serial.println("FEHLER"); // BMP Format nicht unterstützt
 | 
95  | }
  |