LVGL Image Converter — Image to C Array

Convert any PNG, JPG or BMP into an LVGL lv_img_dsc_t C array for ESP32 and STM32 color GUIs. Choose RGB565 true color or 1-bit, then drop it straight into lv_img_set_src() — 100% in your browser.

1
Step 1

Upload Your Image

PNG · JPG · BMP · GIF
📷

Click or drag & drop to upload

RGB565 keeps full color; 1-bit for icons

2
Step 2

Preview

🖼Upload an image to see the live preview
3
Step 3

Generate LVGL Array

This LVGL image converter turns any PNG, JPG or BMP into a ready-to-compile lv_img_dsc_t C array for LVGL — the Light and Versatile Graphics Library that powers most modern embedded GUIs on ESP32, STM32 and other microcontrollers. Pick RGB565 true color for a color TFT or 1-bit for a monochrome panel, set your size, and copy a descriptor you can drop straight into lv_img_set_src(). Conversion is 100% in-browser, so even confidential product UI art never leaves your machine.

What is LVGL and what is lv_img_dsc_t?

LVGL is an open-source graphics library for building rich, animated user interfaces on resource-constrained microcontrollers. It is the engine behind countless ESP32 smart-home panels, 3D-printer touchscreens, and STM32 instrument clusters. To show a static image, LVGL uses an lv_img_dsc_t — an image descriptor that bundles a pixel-data byte array with a small header describing the width, height and color format (the header.cf field). This converter builds the whole structure for you, including the correctly sized data_size field that trips up hand-written arrays.

RGB565 vs. 1-bit: which format to pick

For a color TFT — ILI9341, ST7789, ST7735 — choose True color RGB565. Each pixel becomes two bytes (5 bits red, 6 green, 5 blue) stored little-endian, matching LVGL's default LV_IMG_CF_TRUE_COLOR on a 16-bit display. For a monochrome OLED or an alpha mask, choose 1-bit, which emits LV_IMG_CF_ALPHA_1BIT. RGB565 is the right default for almost every touchscreen project; 1-bit keeps flash usage tiny when you only need a logo or icon outline.

Setting up LVGL on an ESP32

A typical ESP32 + LVGL stack uses the LovyanGFX or TFT_eSPI driver underneath LVGL. The essential steps:

  1. Add lvgl to your platformio.ini or Arduino libraries.
  2. Copy lv_conf_template.h to lv_conf.h and set LV_COLOR_DEPTH 16.
  3. If red and blue come out swapped, enable LV_COLOR_16_SWAP 1 — this is the single most common LVGL color bug.
  4. Register your display flush callback with lv_disp_drv_register().

Full example — show the image on screen

Generate your descriptor above (say you named it my_img), then:

#include "lvgl.h"

// <-- paste the generated lv_img_dsc_t (and its _map array) here -->
extern const lv_img_dsc_t my_img;

void show_logo() {
  lv_obj_t * img = lv_img_create(lv_scr_act());
  lv_img_set_src(img, &my_img);
  lv_obj_center(img);
}

That is the whole flow: create an image object, point it at your descriptor, position it. Because the byte array is const, it lives in flash and costs no RAM beyond LVGL's draw buffer.

Reducing flash usage

An RGB565 image costs width × height × 2 bytes of flash — a full 320×240 ILI9341 background is about 150 KB, which can blow the partition budget on a bare ESP32. Three practical ways to cut that: scale the image down to the smallest size that still looks acceptable on the panel; convert decorative icons to 1-bit alpha instead of full color; or, for many images, switch to LVGL's run-time PNG/BMP decoder and store compressed files on SPIFFS/LittleFS rather than embedding raw arrays. For a handful of UI assets, though, the embedded lv_img_dsc_t this tool generates is the simplest, fastest-loading option — no filesystem, no decoder, just a pointer into flash.

LVGL v8 vs v9 note

The output here targets LVGL v8, whose lv_img_dsc_t and LV_IMG_CF_TRUE_COLOR enum are stable and widely used. On LVGL v9 the color-format enums were renamed (for example LV_COLOR_FORMAT_RGB565) and the descriptor is slightly leaner; the raw RGB565 pixel bytes are identical, so you only need to adjust the header.cf value. Keep the byte order little-endian and you are set.

Driving a plain SSD1306 instead of a color GUI? The u8g2 converter or the classic image2cpp tool are a better fit. For e-ink, see the e-paper converter.

Frequently Asked Questions

What is an LVGL image converter? +
An LVGL image converter turns a PNG/JPG/BMP into a C array wrapped in an lv_img_dsc_t descriptor that the LVGL (Light and Versatile Graphics Library) can display with lv_img_set_src(). LVGL is the most popular embedded GUI library for ESP32, STM32 and other MCUs driving color TFT touchscreens. This tool generates the descriptor in your browser, no upload needed.
Which LVGL color format does this generate? +
You can choose True color RGB565 (16-bit, LV_IMG_CF_TRUE_COLOR) for color TFTs, or 1-bit alpha/indexed for monochrome panels. RGB565 is the right choice for the common ILI9341, ST7789 and ST7735 displays. The descriptor sets the matching header.cf field automatically.
How do I show the image in LVGL? +
Paste the generated lv_img_dsc_t into your project (or a separate .c file with a matching extern), then: lv_obj_t * img = lv_img_create(lv_scr_act()); lv_img_set_src(img, &my_img); lv_obj_center(img); The descriptor name is the variable you set before generating.
Does this work with LVGL v8 and v9? +
The generated lv_img_dsc_t structure and LV_IMG_CF_TRUE_COLOR format are compatible with LVGL v8. LVGL v9 renamed some color-format enums (e.g. LV_COLOR_FORMAT_RGB565); if you are on v9, update the header.cf field to the v9 enum — the raw pixel data is identical. The byte order is little-endian RGB565 as expected by LVGL on most targets.
Is the LVGL converter free and private? +
Yes. All conversion happens client-side in your browser via the Canvas API. Your image never leaves your device, there is no signup, and there are no usage limits or watermarks.
Why is my LVGL image showing wrong colors? +
Wrong or swapped colors almost always mean a byte-order or color-depth mismatch. LVGL on most boards expects little-endian RGB565; if red and blue look swapped, enable LV_COLOR_16_SWAP in lv_conf.h (or toggle the byte order in your display driver). Make sure header.cf matches the format you generated here.

More embedded converters

Image to C++ Converter
The classic image2cpp — SSD1306, ST7735, Adafruit GFX & u8g2 byte arrays.
u8g2 Bitmap Converter
Image to u8g2 XBM / drawXBMP byte array for monochrome OLEDs.
E-Paper Image Converter
Image to Waveshare e-paper byte array, incl. black/white/red 3-color.
Adafruit GFX Font Converter
Convert a font to an Adafruit GFX font header (.h) in your browser.
Developer Calculators ↗
Bit/byte, hex, base, color & sizing calculators for embedded work.
JSON & Dev Tools ↗
Format, validate & convert JSON, CSV, base64 and more — 15 tools.