GxEPD2_SD_WriteBitmap.ino 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // GxEPD2_SD_WriteBitmap: utility for Display Library for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
  2. //
  3. // Display Library based on Demo Example from Good Display: http://www.e-paper-display.com/download_list/downloadcategoryid=34&isMode=false.html
  4. //
  5. // Author: Jean-Marc Zingg
  6. //
  7. // Version: see library.properties
  8. //
  9. // Library: https://github.com/ZinggJM/GxEPD2
  10. #include <GxEPD2_BW.h>
  11. #include <GxEPD2_3C.h>
  12. #include <Fonts/FreeMonoBold9pt7b.h>
  13. #include "bitmaps/Bitmaps200x200.h" // 1.54" b/w
  14. //#include "bitmaps/Bitmaps128x250.h" // 2.13" b/w
  15. //#include "bitmaps/Bitmaps128x296.h" // 2.9" b/w
  16. //#include "bitmaps/Bitmaps176x264.h" // 2.7" b/w
  17. //#include "bitmaps/Bitmaps400x300.h" // 4.2" b/w
  18. //#include "bitmaps/Bitmaps640x384.h" // 7.5" b/w
  19. // 3-color
  20. //#include "bitmaps/Bitmaps3c200x200.h" // 1.54" b/w/r
  21. //#include "bitmaps/Bitmaps3c104x212.h" // 2.13" b/w/r
  22. //#include "bitmaps/Bitmaps3c128x296.h" // 2.9" b/w/r
  23. //#include "bitmaps/Bitmaps3c176x264.h" // 2.7" b/w/r
  24. //#include "bitmaps/Bitmaps3c400x300.h" // 4.2" b/w/r
  25. // include SdFat for FAT32 support with long filenames; available through Library Manager
  26. #include <SdFat.h>
  27. #if defined(SdFat_h)
  28. SdFat SD;
  29. #define FileClass SdFile
  30. #define position curPosition
  31. #define seek seekSet
  32. #else
  33. #include <SD.h>
  34. #define FileClass File
  35. #undef SdFat_h
  36. #endif
  37. void setup()
  38. {
  39. Serial.begin(115200);
  40. Serial.print("Initializing SD card...");
  41. if (!SD.begin(SS))
  42. {
  43. Serial.println("initialization failed!");
  44. while (1) yield();
  45. }
  46. Serial.println("initialization done.");
  47. writeBitmaps();
  48. }
  49. void loop()
  50. {
  51. }
  52. void writeBitmap(const char filename[], const uint8_t bitmap[], int16_t w, int16_t h, uint16_t depth = 1);
  53. uint8_t filldata[] = {0x0, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0x0};
  54. void writeBitmaps()
  55. {
  56. #ifdef _GxBitmaps200x200_H_
  57. writeBitmap("logo.bmp", logo200x200, 200, 200);
  58. writeBitmap("logo200x200.bmp", logo200x200, 200, 200);
  59. writeBitmap("first200x200.bmp", first200x200, 200, 200);
  60. writeBitmap("second200x200.bmp", second200x200, 200, 200);
  61. writeBitmap("third200x200.bmp", third200x200, 200, 200);
  62. writeBitmap("fourth200x200.bmp", fourth200x200, 200, 200);
  63. writeBitmap("fifth200x200.bmp", fifth200x200, 200, 200);
  64. writeBitmap("sixth200x200.bmp", sixth200x200, 200, 200);
  65. writeBitmap("senventh200x200.bmp", senventh200x200, 200, 200);
  66. writeBitmap("eighth200x200.bmp", eighth200x200, 200, 200);
  67. #endif
  68. #ifdef _GxBitmaps128x250_H_
  69. writeBitmap("Bitmap128x250_1.bmp", Bitmap128x250_1, 128, 250);
  70. writeBitmap("logo128x250.bmp", logo128x250, 128, 250);
  71. writeBitmap("first128x250.bmp", first128x250, 128, 250);
  72. writeBitmap("second128x250.bmp", second128x250, 128, 250);
  73. writeBitmap("third128x250.bmp", third128x250, 128, 250);
  74. #endif
  75. #ifdef _GxBitmaps128x296_H_
  76. writeBitmap("Bitmap128x296_1.bmp", Bitmap128x296_1, 128, 296);
  77. writeBitmap("logo128x296.bmp", logo128x296, 128, 296);
  78. writeBitmap("first128x296.bmp", first128x296, 128, 296);
  79. writeBitmap("second128x296.bmp", second128x296, 128, 296);
  80. writeBitmap("third128x296.bmp", third128x296, 128, 296);
  81. #endif
  82. #ifdef _GxBitmaps176x264_H_
  83. writeBitmap("Bitmap176x264_1.bmp", Bitmap176x264_1, 176, 264);
  84. writeBitmap("Bitmap176x264_2.bmp", Bitmap176x264_2, 176, 264);
  85. #endif
  86. #ifdef _GxBitmaps400x300_H_
  87. writeBitmap("Bitmap400x300_1.bmp", Bitmap400x300_1, 400, 300);
  88. writeBitmap("Bitmap400x300_2.bmp", Bitmap400x300_2, 400, 300);
  89. #endif
  90. #ifdef _GxBitmaps640x384_H_
  91. writeBitmap("Bitmap640x384_1.bmp", Bitmap640x384_1, 640, 384);
  92. writeBitmap("Bitmap640x384_2.bmp", Bitmap640x384_2, 640, 384);
  93. #endif
  94. // 3-color
  95. #ifdef _GxBitmaps3c200x200_H_
  96. writeBitmap("Bitmap3c200x200_black.bmp", Bitmap3c200x200_black, 200, 200);
  97. writeBitmap("Bitmap3c200x200_red.bmp", Bitmap3c200x200_red, 200, 200);
  98. writeBitmap("WS_Bitmap3c200x200_black.bmp", WS_Bitmap3c200x200_black, 200, 200);
  99. writeBitmap("WS_Bitmap3c200x200_red.bmp", WS_Bitmap3c200x200_red, 200, 200);
  100. #endif
  101. #ifdef _GxBitmaps3c104x212_H_
  102. writeBitmap("Bitmap3c104x212_1_black.bmp", Bitmap3c104x212_1_black, 104, 212);
  103. writeBitmap("Bitmap3c104x212_1_red.bmp", Bitmap3c104x212_1_red, 104, 212);
  104. writeBitmap("Bitmap3c104x212_2_black.bmp", Bitmap3c104x212_2_black, 104, 212);
  105. writeBitmap("Bitmap3c104x212_2_red.bmp", Bitmap3c104x212_2_red, 104, 212);
  106. writeBitmap("WS_Bitmap3c104x212_black.bmp", WS_Bitmap3c104x212_black, 104, 212);
  107. writeBitmap("WS_Bitmap3c104x212_red.bmp", WS_Bitmap3c104x212_red, 104, 212);
  108. #endif
  109. #ifdef _GxBitmaps3c128x296_H_
  110. writeBitmap("Bitmap3c128x296_1_black.bmp", Bitmap3c128x296_1_black, 128, 296);
  111. writeBitmap("Bitmap3c128x296_1_red.bmp", Bitmap3c128x296_1_red, 128, 296);
  112. writeBitmap("Bitmap3c128x296_2_black.bmp", Bitmap3c128x296_2_black, 128, 296);
  113. writeBitmap("Bitmap3c128x296_2_red.bmp", Bitmap3c128x296_2_red, 128, 296);
  114. writeBitmap("WS_Bitmap3c128x296_black.bmp", WS_Bitmap3c128x296_black, 128, 296);
  115. writeBitmap("WS_Bitmap3c128x296_red.bmp", WS_Bitmap3c128x296_red, 128, 296);
  116. #endif
  117. #ifdef _GxBitmaps3c176x264_H_
  118. writeBitmap("Bitmap3c176x264_black.bmp", Bitmap3c176x264_black, 176, 264);
  119. writeBitmap("Bitmap3c176x264_red.bmp", Bitmap3c176x264_red, 176, 264);
  120. #endif
  121. #ifdef _GxBitmaps3c400x300_H_
  122. writeBitmap("Bitmap3c400x300_1_black.bmp", Bitmap3c400x300_1_black, 400, 300);
  123. writeBitmap("Bitmap3c400x300_1_red.bmp", Bitmap3c400x300_1_red, 400, 300);
  124. writeBitmap("Bitmap3c400x300_2_black.bmp", Bitmap3c400x300_2_black, 400, 300);
  125. writeBitmap("Bitmap3c400x300_2_red.bmp", Bitmap3c400x300_2_red, 400, 300);
  126. writeBitmap("WS_Bitmap3c400x300_black.bmp", WS_Bitmap3c400x300_black, 400, 300);
  127. writeBitmap("WS_Bitmap3c400x300_red.bmp", WS_Bitmap3c400x300_red, 400, 300);
  128. #endif
  129. }
  130. void writeBitmap(const char filename[], const uint8_t bitmap[], int16_t w, int16_t h, uint16_t depth)
  131. {
  132. FileClass bitmapFile;
  133. uint32_t rowSizeCode = (w + 8 - depth) * depth / 8;
  134. // BMP rows are padded (if needed) to 4-byte boundary
  135. uint32_t rowSizeBMP = (w * depth / 8 + 3) & ~3;
  136. Serial.print("writeBitmap(\""); Serial.print(filename); Serial.println("\")");
  137. Serial.print("rowSizeCode "); Serial.println(rowSizeCode);
  138. Serial.print("rowSizeBMP "); Serial.println(rowSizeBMP);
  139. uint32_t headerSize = 40;
  140. uint32_t imageOffset = 62;
  141. uint32_t fileSize = imageOffset + h * rowSizeBMP;
  142. #if defined(SdFat_h)
  143. if (bitmapFile.open(filename, FILE_WRITE))
  144. #else
  145. bitmapFile = SD.open(filename, FILE_WRITE);
  146. if (bitmapFile)
  147. #endif
  148. {
  149. bitmapFile.seek(0);
  150. write16(bitmapFile, 0x4D42); // BMP signature
  151. write32(bitmapFile, fileSize); // fileSize
  152. write32(bitmapFile, 0); // creator bytes
  153. write32(bitmapFile, imageOffset); // image offset
  154. write32(bitmapFile, headerSize); // Header size
  155. write32(bitmapFile, w); // image width
  156. write32(bitmapFile, h); // image height
  157. write16(bitmapFile, 1); // # planes
  158. write16(bitmapFile, depth); // // bits per pixel
  159. write32(bitmapFile, 0); // format uncompressed
  160. //Serial.print("first position "); Serial.println(bitmapFile.position());
  161. uint32_t j = 0;
  162. for (uint32_t i = bitmapFile.position(); i < imageOffset; i++)
  163. {
  164. //bitmapFile.write(uint8_t(0)); // remaining header bytes
  165. bitmapFile.write(filldata[j++]); // remaining header bytes
  166. }
  167. //Serial.print("start position "); Serial.println(bitmapFile.position());
  168. uint32_t rowidx = 0;
  169. for (uint16_t row = 0; row < h; row++) // for each line
  170. {
  171. uint32_t colidx;
  172. for (colidx = 0; colidx < rowSizeCode; colidx++)
  173. {
  174. #if defined(__AVR) || defined(ESP8266) || defined(ESP32)
  175. uint8_t data = pgm_read_byte(&bitmap[rowidx + colidx]);
  176. #else
  177. uint8_t data = bitmap[rowidx + colidx];
  178. #endif
  179. bitmapFile.write(data);
  180. }
  181. rowidx += rowSizeCode;
  182. while (colidx++ < rowSizeBMP) bitmapFile.write(uint8_t (0)); // padding
  183. //Serial.println(bitmapFile.position());
  184. }
  185. bitmapFile.close();
  186. Serial.println("done");
  187. }
  188. else Serial.print("open file for write failed!");
  189. }
  190. void write16(FileClass& f, uint16_t v)
  191. {
  192. f.write(uint8_t(v));
  193. f.write(uint8_t(v >> 8));
  194. }
  195. void write32(FileClass& f, uint32_t v)
  196. {
  197. f.write(uint8_t(v));
  198. f.write(uint8_t(v >> 8));
  199. f.write(uint8_t(v >> 16));
  200. f.write(uint8_t(v >> 24));
  201. }