acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
TFT_flash_jpg.ino (7781B)
1 // Sketch to display images on a 160 x 128 TFT 2 3 // Renders images stored in an array in program (FLASH) 4 // The JPEG images are stored in header files (see jpeg1.h etc) 5 6 // As well as the TFT_eSPI library: 7 // https://github.com/Bodmer/TFT_eSPI 8 // the sketch needs the JPEG Decoder library. This can be loaded via the Library Manager. 9 // or can be downloaded here: 10 // https://github.com/Bodmer/JPEGDecoder 11 12 //---------------------------------------------------------------------------------------------------- 13 14 #include <SPI.h> 15 #include <TFT_eSPI.h> 16 17 TFT_eSPI tft = TFT_eSPI(); 18 19 20 // JPEG decoder library 21 #include <JPEGDecoder.h> 22 23 // Return the minimum of two values a and b 24 #define minimum(a,b) (((a) < (b)) ? (a) : (b)) 25 26 // Include the sketch header file that contains the image stored as an array of bytes 27 // More than one image array could be stored in each header file. 28 #include "jpeg1.h" 29 #include "jpeg2.h" 30 #include "jpeg3.h" 31 #include "jpeg4.h" 32 33 // Count how many times the image is drawn for test purposes 34 uint32_t icount = 0; 35 //---------------------------------------------------------------------------------------------------- 36 37 38 //#################################################################################################### 39 // Setup 40 //#################################################################################################### 41 void setup() { 42 Serial.begin(115200); 43 tft.begin(); 44 } 45 46 //#################################################################################################### 47 // Main loop 48 //#################################################################################################### 49 void loop() { 50 51 tft.setRotation(0); // portrait 52 tft.fillScreen(TFT_BLACK); 53 54 drawArrayJpeg(EagleEye, sizeof(EagleEye), 0, 16); // Draw a jpeg image stored in memory at x,y 55 delay(2000); 56 57 tft.setRotation(0); // portrait 58 tft.fillScreen(TFT_BLACK); 59 drawArrayJpeg(Tiger, sizeof(Tiger), 4, 0); // Draw a jpeg image stored in memory 60 delay(2000); 61 62 tft.setRotation(1); // landscape 63 tft.fillScreen(TFT_BLACK); 64 drawArrayJpeg(Baboon, sizeof(Baboon), 0, 4); // Draw a jpeg image stored in memory 65 delay(2000); 66 67 tft.setRotation(1); // landscape 68 tft.fillScreen(TFT_BLACK); 69 drawArrayJpeg(Mouse160, sizeof(Mouse160), 0, 11); // Draw a jpeg image stored in memory 70 71 delay(2000); 72 } 73 74 //#################################################################################################### 75 // Draw a JPEG on the TFT pulled from a program memory array 76 //#################################################################################################### 77 void drawArrayJpeg(const uint8_t arrayname[], uint32_t array_size, int xpos, int ypos) { 78 79 int x = xpos; 80 int y = ypos; 81 82 JpegDec.decodeArray(arrayname, array_size); 83 84 jpegInfo(); // Print information from the JPEG file (could comment this line out) 85 86 renderJPEG(x, y); 87 88 Serial.println("#########################"); 89 } 90 91 //#################################################################################################### 92 // Draw a JPEG on the TFT, images will be cropped on the right/bottom sides if they do not fit 93 //#################################################################################################### 94 // This function assumes xpos,ypos is a valid screen coordinate. For convenience images that do not 95 // fit totally on the screen are cropped to the nearest MCU size and may leave right/bottom borders. 96 void renderJPEG(int xpos, int ypos) { 97 98 // retrieve infomration about the image 99 uint16_t *pImg; 100 uint16_t mcu_w = JpegDec.MCUWidth; 101 uint16_t mcu_h = JpegDec.MCUHeight; 102 uint32_t max_x = JpegDec.width; 103 uint32_t max_y = JpegDec.height; 104 105 // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs) 106 // Typically these MCUs are 16x16 pixel blocks 107 // Determine the width and height of the right and bottom edge image blocks 108 uint32_t min_w = minimum(mcu_w, max_x % mcu_w); 109 uint32_t min_h = minimum(mcu_h, max_y % mcu_h); 110 111 // save the current image block size 112 uint32_t win_w = mcu_w; 113 uint32_t win_h = mcu_h; 114 115 // record the current time so we can measure how long it takes to draw an image 116 uint32_t drawTime = millis(); 117 118 // save the coordinate of the right and bottom edges to assist image cropping 119 // to the screen size 120 max_x += xpos; 121 max_y += ypos; 122 123 // read each MCU block until there are no more 124 while (JpegDec.readSwappedBytes()) { 125 126 // save a pointer to the image block 127 pImg = JpegDec.pImage ; 128 129 // calculate where the image block should be drawn on the screen 130 int mcu_x = JpegDec.MCUx * mcu_w + xpos; // Calculate coordinates of top left corner of current MCU 131 int mcu_y = JpegDec.MCUy * mcu_h + ypos; 132 133 // check if the image block size needs to be changed for the right edge 134 if (mcu_x + mcu_w <= max_x) win_w = mcu_w; 135 else win_w = min_w; 136 137 // check if the image block size needs to be changed for the bottom edge 138 if (mcu_y + mcu_h <= max_y) win_h = mcu_h; 139 else win_h = min_h; 140 141 // copy pixels into a contiguous block 142 if (win_w != mcu_w) 143 { 144 uint16_t *cImg; 145 int p = 0; 146 cImg = pImg + win_w; 147 for (int h = 1; h < win_h; h++) 148 { 149 p += mcu_w; 150 for (int w = 0; w < win_w; w++) 151 { 152 *cImg = *(pImg + w + p); 153 cImg++; 154 } 155 } 156 } 157 158 // draw image MCU block only if it will fit on the screen 159 if (( mcu_x + win_w ) <= tft.width() && ( mcu_y + win_h ) <= tft.height()) 160 { 161 tft.pushRect(mcu_x, mcu_y, win_w, win_h, pImg); 162 } 163 else if ( (mcu_y + win_h) >= tft.height()) JpegDec.abort(); // Image has run off bottom of screen so abort decoding 164 } 165 166 // calculate how long it took to draw the image 167 drawTime = millis() - drawTime; 168 169 // print the results to the serial port 170 Serial.print(F( "Total render time was : ")); Serial.print(drawTime); Serial.println(F(" ms")); 171 Serial.println(F("")); 172 } 173 174 //#################################################################################################### 175 // Print image information to the serial port (optional) 176 //#################################################################################################### 177 void jpegInfo() { 178 Serial.println(F("===============")); 179 Serial.println(F("JPEG image info")); 180 Serial.println(F("===============")); 181 Serial.print(F( "Width :")); Serial.println(JpegDec.width); 182 Serial.print(F( "Height :")); Serial.println(JpegDec.height); 183 Serial.print(F( "Components :")); Serial.println(JpegDec.comps); 184 Serial.print(F( "MCU / row :")); Serial.println(JpegDec.MCUSPerRow); 185 Serial.print(F( "MCU / col :")); Serial.println(JpegDec.MCUSPerCol); 186 Serial.print(F( "Scan type :")); Serial.println(JpegDec.scanType); 187 Serial.print(F( "MCU width :")); Serial.println(JpegDec.MCUWidth); 188 Serial.print(F( "MCU height :")); Serial.println(JpegDec.MCUHeight); 189 Serial.println(F("===============")); 190 } 191 192 //#################################################################################################### 193 // Show the execution time (optional) 194 //#################################################################################################### 195 // WARNING: for UNO/AVR legacy reasons printing text to the screen with the Mega might not work for 196 // sketch sizes greater than ~70KBytes because 16 bit address pointers are used in some libraries. 197 198 // The Due will work fine with the HX8357_Due library. 199 200 void showTime(uint32_t msTime) { 201 //tft.setCursor(0, 0); 202 //tft.setTextFont(1); 203 //tft.setTextSize(2); 204 //tft.setTextColor(TFT_WHITE, TFT_BLACK); 205 //tft.print(F(" JPEG drawn in ")); 206 //tft.print(msTime); 207 //tft.println(F(" ms ")); 208 Serial.print(F(" JPEG drawn in ")); 209 Serial.print(msTime); 210 Serial.println(F(" ms ")); 211 } 212