@@ -412,88 +412,100 @@ bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t
412
412
return true ;
413
413
}
414
414
415
- bool OpenStreetMap::saveMap (const char *filename, LGFX_Sprite &map, String &result, uint8_t sdPin)
415
+ bool OpenStreetMap::saveMap (const char *filename, LGFX_Sprite &map, String &result, uint8_t sdPin, uint32_t frequency )
416
416
{
417
417
log_i (" Saving map, this may take a while..." );
418
418
419
419
if (!map.getBuffer ())
420
420
{
421
- result = " No data in map! " ;
421
+ result = " No data in map" ;
422
422
return false ;
423
423
}
424
424
425
- if (!SD.begin (sdPin))
425
+ if (!SD.begin (sdPin, SPI, frequency ))
426
426
{
427
- result = " SD Card mount failed! " ;
427
+ result = " SD Card mount failed" ;
428
428
return false ;
429
429
}
430
430
431
431
File file = SD.open (filename, FILE_WRITE);
432
432
if (!file)
433
433
{
434
- result = " Failed to open file! " ;
434
+ result = " Failed to open file" ;
435
435
SD.end ();
436
436
return false ;
437
437
}
438
438
439
- // BMP header (54 bytes)
440
- uint16_t bfType = 0x4D42 ; // "BM"
441
- uint32_t bfSize = 54 + map.width () * map.height () * 3 ; // Header + pixel data ( 3 bytes per pixel for RGB888)
442
- uint16_t bfReserved = 0 ;
443
- uint32_t bfOffBits = 54 ; // Offset to pixel data
439
+ // BMP Header (54 bytes)
440
+ uint16_t bfType = 0x4D42 ; // "BM"
441
+ uint32_t biSizeImage = map.width () * map.height () * 3 ; // 3 bytes per pixel ( RGB888)
442
+ uint32_t bfSize = 54 + biSizeImage; // Total file size
443
+ uint32_t bfOffBits = 54 ; // Offset to pixel data
444
444
445
445
uint32_t biSize = 40 ; // Info header size
446
446
int32_t biWidth = map.width ();
447
- int32_t biHeight = -map.height (); // Negative to flip vertically
447
+ int32_t biHeight = -map.height (); // Negative to store in top-down order
448
448
uint16_t biPlanes = 1 ;
449
449
uint16_t biBitCount = 24 ; // RGB888 format
450
450
uint32_t biCompression = 0 ;
451
- uint32_t biSizeImage = map.width () * map.height () * 3 ; // 3 bytes per pixel
452
451
int32_t biXPelsPerMeter = 0 ;
453
452
int32_t biYPelsPerMeter = 0 ;
454
453
uint32_t biClrUsed = 0 ;
455
454
uint32_t biClrImportant = 0 ;
456
455
457
- // Write BMP header
458
- file.write (reinterpret_cast <const uint8_t *>(&bfType), sizeof (bfType));
459
- file.write (reinterpret_cast <const uint8_t *>(&bfSize), sizeof (bfSize));
460
- file.write (reinterpret_cast <const uint8_t *>(&bfReserved), sizeof (bfReserved));
461
- file.write (reinterpret_cast <const uint8_t *>(&bfOffBits), sizeof (bfOffBits));
462
-
463
- file.write (reinterpret_cast <const uint8_t *>(&biSize), sizeof (biSize));
464
- file.write (reinterpret_cast <const uint8_t *>(&biWidth), sizeof (biWidth));
465
- file.write (reinterpret_cast <const uint8_t *>(&biHeight), sizeof (biHeight));
466
- file.write (reinterpret_cast <const uint8_t *>(&biPlanes), sizeof (biPlanes));
467
- file.write (reinterpret_cast <const uint8_t *>(&biBitCount), sizeof (biBitCount));
468
- file.write (reinterpret_cast <const uint8_t *>(&biCompression), sizeof (biCompression));
469
- file.write (reinterpret_cast <const uint8_t *>(&biSizeImage), sizeof (biSizeImage));
470
- file.write (reinterpret_cast <const uint8_t *>(&biXPelsPerMeter), sizeof (biXPelsPerMeter));
471
- file.write (reinterpret_cast <const uint8_t *>(&biYPelsPerMeter), sizeof (biYPelsPerMeter));
472
- file.write (reinterpret_cast <const uint8_t *>(&biClrUsed), sizeof (biClrUsed));
473
- file.write (reinterpret_cast <const uint8_t *>(&biClrImportant), sizeof (biClrImportant));
456
+ // Write BMP header (Ensuring little-endian format)
457
+ auto writeLE = [&](uint32_t value, uint8_t size)
458
+ {
459
+ for (uint8_t i = 0 ; i < size; i++)
460
+ file.write (static_cast <uint8_t >(value >> (8 * i)));
461
+ };
462
+
463
+ writeLE (bfType, 2 );
464
+ writeLE (bfSize, 4 );
465
+ writeLE (0 , 2 ); // bfReserved
466
+ writeLE (0 , 2 );
467
+ writeLE (bfOffBits, 4 );
468
+
469
+ writeLE (biSize, 4 );
470
+ writeLE (biWidth, 4 );
471
+ writeLE (biHeight, 4 );
472
+ writeLE (biPlanes, 2 );
473
+ writeLE (biBitCount, 2 );
474
+ writeLE (biCompression, 4 );
475
+ writeLE (biSizeImage, 4 );
476
+ writeLE (biXPelsPerMeter, 4 );
477
+ writeLE (biYPelsPerMeter, 4 );
478
+ writeLE (biClrUsed, 4 );
479
+ writeLE (biClrImportant, 4 );
480
+
481
+ MemoryBuffer rowBuffer (map.width () * 3 );
482
+ if (!rowBuffer.isAllocated ())
483
+ {
484
+ result = " Row buffer allocation failed" ;
485
+ file.close ();
486
+ SD.end ();
487
+ return false ;
488
+ }
474
489
490
+ uint8_t *buf = rowBuffer.get ();
475
491
for (int y = 0 ; y < map.height (); y++)
476
492
{
477
493
for (int x = 0 ; x < map.width (); x++)
478
494
{
479
- uint16_t rgb565Color = map.readPixel (x, y); // Read pixel color (RGB565 format)
480
- uint8_t red5 = (rgb565Color >> 11 ) & 0x1F ;
481
- uint8_t green6 = (rgb565Color >> 5 ) & 0x3F ;
482
- uint8_t blue5 = rgb565Color & 0x1F ;
483
-
484
- // Convert RGB565 to RGB888
485
- uint8_t red8 = (red5 * 255 ) / 31 ;
486
- uint8_t green8 = (green6 * 255 ) / 63 ;
487
- uint8_t blue8 = (blue5 * 255 ) / 31 ;
488
-
489
- file.write (blue8);
490
- file.write (green8);
491
- file.write (red8);
495
+ uint16_t rgb565Color = map.readPixel (x, y);
496
+ uint8_t red8 = ((rgb565Color >> 11 ) & 0x1F ) * 255 / 31 ;
497
+ uint8_t green8 = ((rgb565Color >> 5 ) & 0x3F ) * 255 / 63 ;
498
+ uint8_t blue8 = (rgb565Color & 0x1F ) * 255 / 31 ;
499
+
500
+ buf[x * 3 ] = blue8;
501
+ buf[x * 3 + 1 ] = green8;
502
+ buf[x * 3 + 2 ] = red8;
492
503
}
504
+ file.write (buf, rowBuffer.size ()); // Write entire row at once
493
505
}
494
506
495
507
file.close ();
496
508
SD.end ();
497
509
result = " Screenshot saved" ;
498
510
return true ;
499
- }
511
+ }
0 commit comments