Click here to Skip to main content
15,851,242 members
Articles / Programming Languages / C#

Img2Cpp: Create C++ Headers for Embedding Images

Rate me:
Please Sign up or sign in to vote.
4.76/5 (8 votes)
5 Jul 2022MIT2 min read 10K   225   9   8
Easily embed image data into your code
This is a handy tool for embedding images inside your C++ binary.

img2cpp

Introduction

If you've coded significantly for IoT, you've probably run into situations where you need bitmapped pixel data from images made available to your code. These little devices can't just take JPG or PNG resources and display them.

IoT may not be the only time you need something like this. It may be useful for embedding little toolbar or icon images if you're targeting platforms that don't have a resource fork in the binary.

Using this Mess

First, there are two executables: img2cpp and img2cppw. They both do the same thing, but the former is a command line tool and the latter is a GUI based tool. Let's take a look at the usage screen for the command line tool, which will help clarify both:

Usage: img2cpp.exe <imagefile> [/name <name>] [/jpg|/16bpp]
  [/gfx14|/gfx17] [/be]
  [/resize [<width>][x<height>]]
  [/arduino] [/out: <headerfile>]

  <imagefile>   The image to convert
  <name>        The base name to use in the header
  <jpg>         Embed as JPG image
  <16bpp>       Convert to 16bpp
  <gfx14/gfx17> Use gfx14 or 17 bindings
  <be>          Use big-endian format
  <resize>      Resize the image. If one dimension
                isn't specified, the aspect ratio
                is preserved.
  <arduino>     Create code for Arduino
  <headerfile>  The output header to generate

imagefile can be any image.

The name will indicate the name of the image in your code. Depending on the code generated, referring to this name will either get you to the byte array for the pixels (cpp), or to the actual bitmap for the pixels (gfx14/gfx17). Referring to <name>_size will get you to a struct that indicates the size of the bitmap.

jpg indicates that the embedded data will be a JPG stream. This option is not compatible with be or 16bpp.

16bpp means the pixel data should be converted to RGB565 format. Otherwise, it will be RGB888.

gfx14/gfx17 indicates that code will be generated that uses the htcw_gfx graphics library, using either the C++14 or the C++17 standard.

be indicates that big endian output should be used. Often, for IoT, this is the case, since most of the display controllers expect pixel data in big endian format.

resize indicates that the image should be resized. The format is <width>x<height> to resize for both the width and the height, <width>, to resize the width and maintain the aspect ratio or x<height> to do the same but with the height.

arduino indicates that code should be generated for the Arduino framework. The array will be created in program flash (PROGMEM).

headerfile indicates the output file to use. If the command line doesn't specify this, output is directed to stdout.

Coding this Mess

Once your header file is generated and included into your project, how you use it depends on the type of code generated. The following snippets assume name from above is my_image.

Standard C++

C++
// the raw pixel data:
const uint8_t* px0ptr = my_image;
// the size of the bitmap
uint16_t width = my_image_size.width;
uint16_t height = my_image_size.height;

There is of course, no drawing code included with this. It's up to you to render or otherwise use the pixel data in your code.

gfx14/gfx17

C++
// the raw pixel data (not needed):
const uint8_t* px0ptr = my_image_data;
// the size of the bitmap (not needed)
uint16_t width = my_image_size.width;
uint16_t height = my_image_size.height;
// the bitmap (use this)
my_image_t bmp = my_image;

With htcw_gfx, you can draw my_image to your lcd like so:

C++
draw::bitmap(lcd,lcd.bounds(),my_image,my_image.bounds());

Disclaimer

I haven't tested all combinations of options yet. If you find something that doesn't work for you, leave a remark in the comments and I'll get on it.

History

  • 29th June, 2022 - Initial submission
  • 29th June, 2022 - Fixed bug with jpg generation under gfx

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
United States United States
Just a shiny lil monster. Casts spells in C++. Mostly harmless.

Comments and Discussions

 
QuestionExpired Websit Cert :( Pin
GrahamHanson6-Jul-22 4:10
professionalGrahamHanson6-Jul-22 4:10 
AnswerRe: Expired Websit Cert :( Pin
honey the codewitch6-Jul-22 4:37
mvahoney the codewitch6-Jul-22 4:37 
AnswerRe: Expired Websit Cert :( Pin
honey the codewitch6-Jul-22 12:13
mvahoney the codewitch6-Jul-22 12:13 
QuestionNeed to change a line. Pin
merano992-Jul-22 5:38
mvemerano992-Jul-22 5:38 
In Img2CppGen.cs the line
Rectangle r = default;
did not compile. I replaced it with
Rectangle r = new Rectangle(0, 0, size.Width, size.Height);
That seems to be working. What does "default" mean?
AnswerRe: Need to change a line. Pin
honey the codewitch2-Jul-22 5:49
mvahoney the codewitch2-Jul-22 5:49 
QuestionNice Utility Pin
Mike Hankey30-Jun-22 8:58
mveMike Hankey30-Jun-22 8:58 
AnswerRe: Nice Utility Pin
honey the codewitch30-Jun-22 10:38
mvahoney the codewitch30-Jun-22 10:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.