{"id":161779,"date":"2024-08-22T13:22:17","date_gmt":"2024-08-22T13:22:17","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=161779"},"modified":"2024-11-02T10:22:36","modified_gmt":"2024-11-02T10:22:36","slug":"esp32-tft-display-image-lvgl-arduino","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-tft-display-image-lvgl-arduino\/","title":{"rendered":"ESP32 with TFT: Display Image using LVGL \u2013 2.8 inch ILI9341 240\u00d7320 (Arduino)"},"content":{"rendered":"\n<p>In this guide, you&#8217;ll learn how to process and load an image to be displayed on a TFT 2.8 inch ILI9341 240\u00d7320 with the ESP32 board using LVGL (Light Versatile Graphics Library). The ESP32 will be programmed using Arduino IDE.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-TFT-Display-Image-LVGL-2_8-inch-ILI9341-240%C3%97320-Arduino-IDE.jpg?resize=1024%2C576&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 with TFT Display Image using LVGL \u2013 2.8 inch ILI9341 240\u00d7320 Arduino IDE\" class=\"wp-image-161782\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-TFT-Display-Image-LVGL-2_8-inch-ILI9341-240%C3%97320-Arduino-IDE.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-TFT-Display-Image-LVGL-2_8-inch-ILI9341-240%C3%97320-Arduino-IDE.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-TFT-Display-Image-LVGL-2_8-inch-ILI9341-240%C3%97320-Arduino-IDE.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-TFT-Display-Image-LVGL-2_8-inch-ILI9341-240%C3%97320-Arduino-IDE.jpg?resize=1536%2C864&amp;quality=100&amp;strip=all&amp;ssl=1 1536w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-TFT-Display-Image-LVGL-2_8-inch-ILI9341-240%C3%97320-Arduino-IDE.jpg?w=1920&amp;quality=100&amp;strip=all&amp;ssl=1 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclblue\"><strong>Are you using a CYD board?<\/strong> Read this guide: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-cyd-lvgl-display-image\/\">ESP32 CYD with LVGL: Display Image on the Screen<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>In this project, you&#8217;ll learn how to display images on the TFT screen using LVGL. We\u2019ll create an example to display the image of a cat as shown in the picture below, but you can modify it to load any other image.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"446\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-TFT-LCD-with-LVGL-Display-Image-on-the-screen-demonstration.png?resize=750%2C446&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 TFT LCD with LVGL Display Image on the screen demonstration\" class=\"wp-image-161784\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-TFT-LCD-with-LVGL-Display-Image-on-the-screen-demonstration.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-TFT-LCD-with-LVGL-Display-Image-on-the-screen-demonstration.png?resize=300%2C178&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before proceeding, make sure you follow the next prerequisites.<strong> You must follow all steps, otherwise, your project will not work.<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1) Parts Required<\/h3>\n\n\n\n<p>For this project, you need the following parts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/2-8-inch-ili9341-tft-240x320\/\" target=\"_blank\" rel=\"noreferrer noopener\">TFT LCD Touchscreen Display \u2013 2.8 inch ILI9341 240\u00d7320<\/a><\/li>\n\n\n\n<li>ESP32 board with enough pins to wire the display (for example an <a href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\" rel=\"noopener\" title=\"\">ESP32 DOIT V1 board<\/a>)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2) Install ESP32 Boards in Arduino IDE<\/h3>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"204\" height=\"204\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?resize=204%2C204&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Arduino IDE 2 Logo\" class=\"wp-image-159109\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?w=204&amp;quality=100&amp;strip=all&amp;ssl=1 204w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/arduino-ide-2.jpg?resize=150%2C150&amp;quality=100&amp;strip=all&amp;ssl=1 150w\" sizes=\"(max-width: 204px) 100vw, 204px\" \/><\/figure><\/div>\n\n\n<p>We&#8217;ll program the ESP32 using Arduino IDE. Make sure you have the ESP32 boards installed. Follow the next tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/installing-esp32-arduino-ide-2-0\/\" title=\"\">Installing ESP32 Board in Arduino IDE 2 (Windows, Mac OS X, Linux)<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3) Get familiar with the ILI9341 TFT LCD Touchscreen Display<\/h3>\n\n\n\n<p>The display we\u2019re using in this guide is the 2.8. inch TFT LCD that also comes with a touchscreen. The display communicates via SPI communication protocol and uses the ILI9341 driver. The touchscreen also uses the SPI communication protocol.<\/p>\n\n\n\n<p>The TFT LCD touchscreen also comes with an SD card interface if you need to load files for your specific project. This display is also available with different screen sizes, but we&#8217;ll use the one with 240 x 320 pixels).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/TFT-LCD-Touchscreen-display.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ILI9341 TFT LCD Touchscreen Display\" class=\"wp-image-150003\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/TFT-LCD-Touchscreen-display.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/TFT-LCD-Touchscreen-display.jpg?resize=300%2C168&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>If this is your first time using this display, make sure to follow our getting started guide:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/randomnerdtutorials.com\/lvgl-esp32-tft-touchscreen-display-ili9341-arduino\/\" title=\"\">ESP32 with LVGL: TFT LCD Touchscreen Display \u2013 2.8 inch ILI9341 240\u00d7320 (Arduino IDE)<\/a><\/strong><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4) Wire the Display to the ESP32<\/h3>\n\n\n\n<p>Wire the TFT LCD and touchscreen pins to the ESP32 GPIOs according to the next table (you must use these exact pins, otherwise the project will not work).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-TFT-Display-Screen-Wiring.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Wiring TFT LCD Touchscreen display to ESP32\" class=\"wp-image-150007\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-TFT-Display-Screen-Wiring.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-TFT-Display-Screen-Wiring.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>TFT LCD Touchscreen<\/strong><\/td><td><strong>ESP32<\/strong><\/td><\/tr><tr><td>T_IRQ<\/td><td>GPIO 36<\/td><\/tr><tr><td>T_OUT<\/td><td>GPIO 39<\/td><\/tr><tr><td>T_DIN<\/td><td>GPIO 32<\/td><\/tr><tr><td>T_CS<\/td><td>GPIO 33<\/td><\/tr><tr><td>T_CLK<\/td><td>GPIO 25<\/td><\/tr><tr><td>SDO(MISO)<\/td><td>GPIO 12<\/td><\/tr><tr><td>LED<\/td><td>GPIO 21<\/td><\/tr><tr><td>SCK<\/td><td>GPIO 14<\/td><\/tr><tr><td>SDI(MOSI)<\/td><td>GPIO 13<\/td><\/tr><tr><td>D\/C<\/td><td>GPIO 2<\/td><\/tr><tr><td>RESET<\/td><td>EN\/RESET<\/td><\/tr><tr><td>CS<\/td><td>GPIO 15<\/td><\/tr><tr><td>GND<\/td><td>GND<\/td><\/tr><tr><td>VCC<\/td><td>5V (or 3.3V)*<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>* In the VCC pin, you can either use 5V or 3.3V depending if your <strong>J1<\/strong> connection is open or closed (by default it&#8217;s usually open as you can see in the figure below).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>VCC = 5V | J1=OPEN\nVCC = 3.3V | J1=CLOSE<\/code><\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/TFT-LCD-touchscreen-J1-connection.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"TFT LCD Touchscreen display J1 connection\" class=\"wp-image-150009\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/TFT-LCD-touchscreen-J1-connection.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/TFT-LCD-touchscreen-J1-connection.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">5) Install TFT and LVGL Libraries<\/h3>\n\n\n\n<p><a href=\"https:\/\/docs.lvgl.io\/master\/\" target=\"_blank\" rel=\"noreferrer noopener\">LVGL<\/a>&nbsp;(Light and Versatile Graphics Library) is a free and open-source graphics library that provides a wide range of easy-to-use graphical elements for your microcontroller projects that require a graphical user interface (GUI).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"622\" height=\"194\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-new-logo.png?resize=622%2C194&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"LVGL new logo\" class=\"wp-image-161339\" style=\"width:340px\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-new-logo.png?w=622&amp;quality=100&amp;strip=all&amp;ssl=1 622w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-new-logo.png?resize=300%2C94&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 622px) 100vw, 622px\" \/><\/figure><\/div>\n\n\n<p>Follow the next tutorial to install and configure the required libraries to use LVGL with the ESP32 using Arduino IDE and the TFT LCD touchscreen.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/lvgl-esp32-tft-touchscreen-display-ili9341-arduino\/\" title=\"\"><strong>LVGL with ESP32 TFT LCD Touchscreen Display \u2013 2.8 inch ILI9341 240\u00d7320 (Arduino IDE)<\/strong><\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Preparing the Image File &#8211; <em>image.h<\/em><\/h2>\n\n\n\n<p>To load a custom image using LVGL, you need to create and configure a file called <em>image.h<\/em> that must be placed inside the sketch folder. We already prepared that file for you. If you want to load a custom image, you just need to replace the image <span class=\"rnthl rntliteral\">uint8_t map<\/span> and the image size.<\/p>\n\n\n\n<p>You can use our sample image or follow the next steps to prepare a custom image:<\/p>\n\n\n\n<p>1. Go to the LVGL Image Converter Website: <a href=\"https:\/\/lvgl.io\/tools\/imageconverter\" target=\"_blank\" rel=\"noopener\" title=\"\">lvgl.io\/tools\/imageconverter<\/a><\/p>\n\n\n\n<p>2. Select the following options highlighted in the image below:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Version: LVGL v9<\/li>\n\n\n\n<li>Select an image from your computer<\/li>\n\n\n\n<li>Color format: ARGB8888<\/li>\n\n\n\n<li>Then, click the <strong>Convert<\/strong> button<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"708\" height=\"680\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-Image-Converter-LVGL-v9-ARGB8888.png?resize=708%2C680&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"LVGL Image Converter website LVGL.io v9 ARGB8888\" class=\"wp-image-161693\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-Image-Converter-LVGL-v9-ARGB8888.png?w=708&amp;quality=100&amp;strip=all&amp;ssl=1 708w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-Image-Converter-LVGL-v9-ARGB8888.png?resize=300%2C288&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 708px) 100vw, 708px\" \/><\/figure><\/div>\n\n\n<p>3. It will download a file with the name of your picture but with the <em>.c<\/em> extension. Open that file and copy the code between <span class=\"rnthl rntliteral\">brackets { }<\/span> with many hexadecimal characters.<\/p>\n\n\n\n<p>4. Create a new file called <em>image.h<\/em>.<\/p>\n\n\n\n<p>5. <strong><a href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/ESP32-TFT-Touchscreen\/main\/examples\/display-images\/image.h\" target=\"_blank\" rel=\"noopener\" title=\"\">Copy the code in this repository<\/a><\/strong> and paste it into the new <em>image.h<\/em> file that you&#8217;ve just created.<\/p>\n\n\n\n<p>6. Replace the content of the <span class=\"rnthl rntliteral\">my_image_map<\/span> variable with the content you\u2019ve just copied in step 3. (<strong>Don\u2019t change the name<\/strong> of the <span class=\"rnthl rntliteral\">my_image_map<\/span> variable, only copy and replace what is between brackets.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-TFT-Touchscreen\/raw\/refs\/heads\/main\/examples\/display-images\/image.zip\" target=\"_blank\" rel=\"noopener\" title=\"\">Click here to download the <em>image.h<\/em> file<\/a><\/strong><\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifdef __has_include\n    #if __has_include(\"lvgl.h\")\n        #ifndef LV_LVGL_H_INCLUDE_SIMPLE\n            #define LV_LVGL_H_INCLUDE_SIMPLE\n        #endif\n    #endif\n#endif\n\n#if defined(LV_LVGL_H_INCLUDE_SIMPLE)\n    #include \"lvgl.h\"\n#else\n    #include \"lvgl\/lvgl.h\"\n#endif\n\n#define LV_BIG_ENDIAN_SYSTEM\n\n#ifndef LV_ATTRIBUTE_MEM_ALIGN\n#define LV_ATTRIBUTE_MEM_ALIGN\n#endif\n\n#ifndef LV_ATTRIBUTE_IMG_MY_IMAGE\n#define LV_ATTRIBUTE_IMG_MY_IMAGE\n#endif\n\nconst LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_MY_IMAGE uint8_t my_image_map&#091;] = {<strong>REPLACE_WITH_YOUR__IMAGE_ATTRIBUTE<\/strong>};\n\nconst lv_image_dsc_t my_image = {\n    .header = {\n        .magic = LV_IMAGE_HEADER_MAGIC,\n        .cf = LV_COLOR_FORMAT_ARGB8888,\n        .flags = 0,          \n        .w = 128,\n        .h = 128,\n        \/\/.stride = 120,\n        .reserved_2 = 0\n    },\n    .data_size = sizeof(my_image_map),\n    .data = my_image_map,\n    .reserved = NULL\n};<\/code><\/pre>\n\n\n\n<p>7. Scroll down on that file and change the following lines with your image width <span class=\"rnthl rntliteral\">.w<\/span> and height <span class=\"rnthl rntliteral\">.h<\/span>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const lv_image_dsc_t my_image = {\n    .header = {\n        .magic = LV_IMAGE_HEADER_MAGIC,\n        .cf = LV_COLOR_FORMAT_ARGB8888,\n        .flags = 0,          \n<strong>        .w = 128,\n        .h = 128,<\/strong>\n        \/\/.stride = 120,\n        .reserved_2 = 0\n    },\n    .data_size = sizeof(my_image_map),\n    .data = my_image_map,\n    .reserved = NULL\n};<\/code><\/pre>\n\n\n\n<p>8. Finally, save your <em>image.h<\/em> file.<\/p>\n\n\n\n<p><strong>Important:<\/strong> the <em>image.h<\/em> file should be placed next to the <em>.ino<\/em> file in the sketch folder of your project.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"267\" height=\"282\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/LVGL-Load-Image-Arduino-Code-example-folder.png?resize=267%2C282&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"LVGL Load Image Arduino Code example folder\" class=\"wp-image-161696\"\/><\/figure><\/div>\n\n\n<p>Your Arduino IDE should have two tabs:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"406\" height=\"123\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/Arduino-IDE-tabs-LVGL-Load-Image-Arduino-Code-example-folder.png?resize=406%2C123&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Arduino IDE tabs LVGL Load Image Arduino Code example folder\" class=\"wp-image-161697\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/Arduino-IDE-tabs-LVGL-Load-Image-Arduino-Code-example-folder.png?w=406&amp;quality=100&amp;strip=all&amp;ssl=1 406w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/Arduino-IDE-tabs-LVGL-Load-Image-Arduino-Code-example-folder.png?resize=300%2C91&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 406px) 100vw, 406px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">ESP32 with TFT LCD: Load and Display Image &#8211; Arduino Code<\/h2>\n\n\n\n<p>The following code will display an image on the screen. You must have prepared the <em>image.h<\/em> previously with the image of your choice. Alternatively, you can use our default <em>image.h<\/em> file. This file should be placed in the sketch folder next to the <em>.ino<\/em> file.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*  Rui Santos &amp; Sara Santos - Random Nerd Tutorials - https:\/\/RandomNerdTutorials.com\/esp32-cyd-lvgl-display-image\/\n    THIS EXAMPLE WAS TESTED WITH THE FOLLOWING HARDWARE:\n    1) ESP32-2432S028R 2.8 inch 240\u00d7320 also known as the Cheap Yellow Display (CYD): https:\/\/makeradvisor.com\/tools\/cyd-cheap-yellow-display-esp32-2432s028r\/\n      SET UP INSTRUCTIONS: https:\/\/RandomNerdTutorials.com\/cyd-lvgl\/\n    2) REGULAR ESP32 Dev Board + 2.8 inch 240x320 TFT Display: https:\/\/makeradvisor.com\/tools\/2-8-inch-ili9341-tft-240x320\/ and https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\n      SET UP INSTRUCTIONS: https:\/\/RandomNerdTutorials.com\/esp32-tft-lvgl\/\n    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.\n    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n*\/\n\n\/*  Install the &quot;lvgl&quot; library version 9.2 by kisvegabor to interface with the TFT Display - https:\/\/lvgl.io\/\n    *** IMPORTANT: lv_conf.h available on the internet will probably NOT work with the examples available at Random Nerd Tutorials ***\n    *** YOU MUST USE THE lv_conf.h FILE PROVIDED IN THE LINK BELOW IN ORDER TO USE THE EXAMPLES FROM RANDOM NERD TUTORIALS ***\n    FULL INSTRUCTIONS AVAILABLE ON HOW CONFIGURE THE LIBRARY: https:\/\/RandomNerdTutorials.com\/cyd-lvgl\/ or https:\/\/RandomNerdTutorials.com\/esp32-tft-lvgl\/   *\/\n#include &lt;lvgl.h&gt;\n\n\/*  Install the &quot;TFT_eSPI&quot; library by Bodmer to interface with the TFT Display - https:\/\/github.com\/Bodmer\/TFT_eSPI\n    *** IMPORTANT: User_Setup.h available on the internet will probably NOT work with the examples available at Random Nerd Tutorials ***\n    *** YOU MUST USE THE User_Setup.h FILE PROVIDED IN THE LINK BELOW IN ORDER TO USE THE EXAMPLES FROM RANDOM NERD TUTORIALS ***\n    FULL INSTRUCTIONS AVAILABLE ON HOW CONFIGURE THE LIBRARY: https:\/\/RandomNerdTutorials.com\/cyd-lvgl\/ or https:\/\/RandomNerdTutorials.com\/esp32-tft-lvgl\/   *\/\n#include &lt;TFT_eSPI.h&gt;\n\n#include &lt;image.h&gt;\n\n#define SCREEN_WIDTH 240\n#define SCREEN_HEIGHT 320\n\n#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT \/ 10 * (LV_COLOR_DEPTH \/ 8))\nuint32_t draw_buf[DRAW_BUF_SIZE \/ 4];\n\n\/\/ If logging is enabled, it will inform the user about what is happening in the library\nvoid log_print(lv_log_level_t level, const char * buf) {\n  LV_UNUSED(level);\n  Serial.println(buf);\n  Serial.flush();\n}\n\nvoid draw_image(void) {\n  LV_IMAGE_DECLARE(my_image);\n  lv_obj_t * img1 = lv_image_create(lv_screen_active());\n  lv_image_set_src(img1, &amp;my_image);\n  lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);\n}\n\nvoid setup() {\n  String LVGL_Arduino = String(&quot;LVGL Library Version: &quot;) + lv_version_major() + &quot;.&quot; + lv_version_minor() + &quot;.&quot; + lv_version_patch();\n  Serial.begin(115200);\n  Serial.println(LVGL_Arduino);\n  \n  \/\/ Start LVGL\n  lv_init();\n  \/\/ Register print function for debugging\n  lv_log_register_print_cb(log_print);\n\n  \/\/ Create a display object\n  lv_display_t * disp;\n  \/\/ Initialize the TFT display using the TFT_eSPI library\n  disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));\n  lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);\n    \n  \/\/ Function to draw the image\n  draw_image();\n}\n\nvoid loop() {\n  lv_task_handler();  \/\/ let the GUI do its work\n  lv_tick_inc(5);     \/\/ tell LVGL how much time has passed\n  delay(5);           \/\/ let this time pass\n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-TFT-Touchscreen\/raw\/main\/examples\/display-images\/ESP32_LVGL_Display_Image.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How Does the Code Work?<\/h2>\n\n\n\n<p>Let\u2019s take a look at how to display an image on the TFT screen. Alternatively, you can skip to the <a href=\"#demonstration\" title=\"\">Demonstration <\/a>section.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Including Libraries<\/h3>\n\n\n\n<p>You need to include the <span class=\"rnthl rntliteral\">lvgl.h<\/span> and the <span class=\"rnthl rntliteral\">TFT_eSPI.h<\/span> libraries to communicate and display text on the screen.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;lvgl.h&gt;\n#include &lt;TFT_eSPI.h&gt;<\/code><\/pre>\n\n\n\n<p>Include the <span class=\"rnthl rntliteral\">image.h<\/span> file that contains all the information to draw the image.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;image.h&gt;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">setup()<\/h3>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, include the following lines for debugging. These will print the version of LVGL that you\u2019re using. You must be using version 9.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String LVGL_Arduino = String(\"LVGL Library Version: \") + lv_version_major() + \".\" + lv_version_minor() + \".\" + lv_version_patch();\nSerial.begin(115200);\nSerial.println(LVGL_Arduino);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Initialize the LVGL Library<\/h4>\n\n\n\n<p>Initialize the LVGL Library by calling the <span class=\"rnthl rntliteral\">lv_init()<\/span> function in the <span class=\"rnthl rntliteral\">setup()<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Start LVGL\nlv_init();<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Register Debugging Function<\/h4>\n\n\n\n<p>Register your <span class=\"rnthl rntliteral\">log_print()<\/span> function declared previously as a function associated with debugging LVGL.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Register print function for debugging\nlv_log_register_print_cb(log_print);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Create a Display Object<\/h4>\n\n\n\n<p>To write to the display, you must create a display object first. You need to do this in all your LVGL sketches. The following lines will create an LVGL display object called <span class=\"rnthl rntliteral\">disp<\/span> with the screen width, screen height, and drawing buffer defined earlier.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Create a display object\nlv_display_t * disp;\n\/\/ Initialize the TFT display using the TFT_eSPI library\ndisp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));\nlv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Drawing the image<\/h4>\n\n\n\n<p>The LVGL library works asynchronously. You must call the function <span class=\"rnthl rntliteral\">draw_image()<\/span> to draw on the display in the <span class=\"rnthl rntliteral\">setup()<\/span>. Then, everything works with events and callbacks. The code will always be listening for events in the background.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>draw_image();<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">draw_image()<\/h3>\n\n\n\n<p>Create a function called <span class=\"rnthl rntliteral\">draw_image()<\/span> that will be called on the <span class=\"rnthl rntliteral\">setup()<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void draw_image(void) {\n  LV_IMAGE_DECLARE(my_image);\n  lv_obj_t * img1 = lv_image_create(lv_screen_active());\n  lv_image_set_src(img1, &amp;my_image);\n  lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);\n}<\/code><\/pre>\n\n\n\n<p>Start by declaring your image using the following line (<span class=\"rnthl rntliteral\">my_image<\/span> is declared on the <em>image.h<\/em> file).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>LV_IMAGE_DECLARE(my_image);<\/code><\/pre>\n\n\n\n<p>Create an image LVGL object on the current screen called <span class=\"rnthl rntliteral\">img1<\/span> using the <span class=\"rnthl rntliteral\">lv_image_create()<\/span> function.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_obj_t * img1 = lv_image_create(lv_screen_active());<\/code><\/pre>\n\n\n\n<p>Set the image source using the <span class=\"rnthl rntliteral\">lv_image_set_src()<\/span> function and pass as arguments the LVGL image object and image source.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_image_set_src(img1, &amp;my_image);<\/code><\/pre>\n\n\n\n<p>Align the image at the center of the screen.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">loop()<\/h3>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">loop()<\/span>, you can add any other tasks that you need your ESP32 to do like in any regular Arduino sketch. In our case, we won\u2019t add any tasks to the <span class=\"rnthl rntliteral\">loop()<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void loop() {\n  lv_task_handler();\n  lv_tick_inc(5);\n  delay(5);\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"demonstration\">Demonstration<\/h2>\n\n\n\n<p>Your<em> image.h<\/em> file should be next to your <em>.ino<\/em> file. The <em>image.h<\/em> file will automatically be uploaded to the board when you upload the code.<\/p>\n\n\n\n<p>After having both files prepared, upload the code to your board. Go to <strong>Tools <\/strong>&gt; <strong>Board <\/strong>and select <strong>ESP32 <\/strong>&gt; <strong>ESP32 Dev Module<\/strong>. Then, select the right COM port in <strong>Tools <\/strong>&gt; <strong>Port<\/strong>. Finally, click the upload button.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"36\" height=\"39\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2021\/05\/arduino-ide-2-upload-button.png?resize=36%2C39&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Arduino IDE 2 Upload Button\" class=\"wp-image-146269\" style=\"width:36px;height:auto\"\/><\/figure><\/div>\n\n\n<p>After a few seconds, the screen will display the image as shown in the picture below.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"423\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-with-TFT-Display-Image-LVGL-2_8-inch-ILI9341-240%C3%97320-Arduino.jpg?resize=750%2C423&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 with TFT Display Image using LVGL \u2013 2.8 inch ILI9341 240\u00d7320 Arduino Code demonstration\" class=\"wp-image-161781\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-with-TFT-Display-Image-LVGL-2_8-inch-ILI9341-240%C3%97320-Arduino.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-with-TFT-Display-Image-LVGL-2_8-inch-ILI9341-240%C3%97320-Arduino.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial, you learned how to display images on the TFT LCD Touchscreen with the ESP32 using the LVGL library.<\/p>\n\n\n\n<p>We hope you found this tutorial useful. We&#8217;re preparing more guides about this board, so stay tuned. If you would like to learn more about creating graphical user interfaces using the LVGL library with the ESP32, check out our latest eBook:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/randomnerdtutorials.com\/learn-lvgl-esp32-ebook\/\">Learn LVGL: Build GUIs for ESP32 Projects (eBook)<\/a><\/strong><\/li>\n<\/ul>\n\n\n\n<p>Other guides you might like reading:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/lvgl-esp32-tft-touchscreen-display-ili9341-arduino\/\">LVGL with ESP32 TFT LCD Touchscreen Display \u2013 2.8 inch ILI9341 240\u00d7320 (Arduino IDE)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-tft-touchscreen-on-off-button-ili9341-arduino\/\">ESP32: TFT Touchscreen On\/Off Button \u2013 2.8 inch ILI9341 240\u00d7320 (Arduino IDE)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-tft-touchscreen-display-2-8-ili9341-arduino\/\">ESP32: TFT LCD Touchscreen Display \u2013 2.8 inch ILI9341 240\u00d7320 (Arduino IDE)<\/a><\/li>\n<\/ul>\n\n\n\n<p>To learn more about the ESP32, make sure to take a look at our resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE (eBook)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/smart-home-ebook\/\" title=\"\">SMART HOME with Raspberry Pi, ESP32, and ESP8266 eBook<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-esp32\/\" title=\"\"><strong>Free ESP32 Guides and Tutorials<\/strong><\/a><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, you&#8217;ll learn how to process and load an image to be displayed on a TFT 2.8 inch ILI9341 240\u00d7320 with the ESP32 board using LVGL (Light Versatile &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32 with TFT: Display Image using LVGL \u2013 2.8 inch ILI9341 240\u00d7320 (Arduino)\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-tft-display-image-lvgl-arduino\/#more-161779\" aria-label=\"Read more about ESP32 with TFT: Display Image using LVGL \u2013 2.8 inch ILI9341 240\u00d7320 (Arduino)\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":1,"featured_media":161782,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[281,276,277,299,264],"tags":[],"class_list":["post-161779","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32-project","category-esp32","category-esp32-arduino-ide","category-0-esp32","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/08\/ESP32-TFT-Display-Image-LVGL-2_8-inch-ILI9341-240%C3%97320-Arduino-IDE.jpg?fit=1920%2C1080&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/161779","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=161779"}],"version-history":[{"count":7,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/161779\/revisions"}],"predecessor-version":[{"id":163673,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/161779\/revisions\/163673"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/161782"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=161779"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=161779"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=161779"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}