Go Down

Topic: .bmp to .cpp on mac (Read 2475 times) previous topic - next topic

zonkzonk

Hello there,

I'm looking for a way to convert .bmp files to .cpp files on mac.
Something like http://en.radzio.dxp.pl/bitmap_converter/ but for osx.

I'm not working with LCD-Displays but with this thermal printer -> http://www.sparkfun.com/products/10438
and want it to print bitmaps.

thanks for any answers

liudr

Nice find for the program. Can you contact the author to supply source code or compile into executable for a mac?

On an another thought, what about this?

http://en.wikipedia.org/wiki/GIMP

Look under the "export only" and keywords c source array ;) Sounds fun. I'll log on as admin and install this to try out myself.

bperrybap

I use the same tool (gimp) but prefer X11 bitmap format.
It is much more compact for simple on/off pixel type images.
The XBM format is very easy to render.
(The glcd library I support will support XBM bitmap format in an upcomming release)

To create it simply save the file as .xbm
You can then compile it directly by either including it or
renaming .c if you want.

But if you wanting this data to be used on an AVR chip say with Arduino
you will have to modify the format slightly to work with the AVR because of the
Harvard architecture and limited RAM.

When dealing with the AVR you will have to put the data in progmem.
In order to do that you must change the .xbm output format slightly
to put the data into progmem.
I also included the width and height into the same data so that the full XBM data is
all self contained.

Sample bitmap image:
Original .xbm format:
Code: [Select]

#define crossblack_width 12
#define crossblack_height 12
static unsigned char crossblack_bits[] = {
   0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f,
   0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f };


Modified  to include width/height and live in AVR progmem:
Code: [Select]

static unsigned char crossblack_xbm[] PROGMEM = {
12,12,
   0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f,
   0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x0f };


To help you get started understanding XBM format, here is the rendering routine from the glcd library:

Code: [Select]
/**
* Draw a glcd bitmap image in x11 XBM bitmap data format
*
* @param bitmapxbm a ponter to the glcd XBM bitmap data
* @param x the x coordinate of the upper left corner of the bitmap
* @param y the y coordinate of the upper left corner of the bitmap
* @param color BLACK or WHITE
*
* Draws a x11 XBM bitmap image with the upper left corner at location x,y
* The glcd xbm bitmap data format consists of 1 byte of width followed by 1 byte of height followed
* by the x11 xbm pixel data bytes.
* The bitmap data is assumed to be in program memory.
*
* Color is optional and defaults to BLACK.
*
* @see DrawBitmapXBM_P()
* @see DrawBitmap()
*/

void glcd::DrawBitmapXBM(ImageXBM_t bitmapxbm, uint8_t x, uint8_t y, uint8_t color)
{
uint8_t width, height;
uint8_t bg_color;
uint8_t *xbmbits;


xbmbits = (uint8_t *) bitmapxbm;

width = ReadPgmData(xbmbits++);
height = ReadPgmData(xbmbits++);

if(color == BLACK)
bg_color = WHITE;
else
bg_color = BLACK;
DrawBitmapXBM_P(width, height, xbmbits, x, y, color, bg_color);
}

/**
* Draw a x11 XBM bitmap image
*
* @param width pixel width of the image
* @param height pixel height of the image
* @param xbmbits a ponter to the XBM bitmap pixel data
* @param x the x coordinate of the upper left corner of the bitmap
* @param y the y coordinate of the upper left corner of the bitmap
* @param fg_color foreground color
* @param bg_color background color
*
* Draws a x11 XBM bitmap image with the upper left corner at location x,y
* The xbm bitmap pixel data format is the same as the X11 bitmap pixel data.
* The bitmap data is assumed to be in program memory.
*
* @note All parameters are mandatory
*
* @see DrawBitmapXBM_P()
* @see DrawBitmap()
*/


void glcd::DrawBitmapXBM_P(uint8_t width, uint8_t height, uint8_t *xbmbits,
uint8_t x, uint8_t y, uint8_t fg_color, uint8_t bg_color)
{
uint8_t xbmx, xbmy;
uint8_t xbmdata;

/*
* Traverse through the XBM data byte by byte and plot pixel by pixel
*/
for(xbmy = 0; xbmy < height; xbmy++)
{
for(xbmx = 0; xbmx < width; xbmx++)
{
if(!(xbmx & 7)) // read the flash data only once per byte
xbmdata = ReadPgmData(xbmbits++);

if(xbmdata & _BV((xbmx & 7)))
this->SetDot(x+xbmx, y+xbmy, fg_color); // XBM 1 bits are fg color
else
this->SetDot(x+xbmx, y+xbmy, bg_color); // XBM 0 bits are bg color
}
}

}





--- bill

bperrybap

#3
Jan 10, 2012, 06:32 am Last Edit: Jan 10, 2012, 06:35 am by bperrybap Reason: 1
I took quick look at the manual and their sample code. From my brief look at both
the data format needed for bitmaps was not obvious.
The sparkfun  bitmap example code is not too helpful in understanding the data format.
And the example in the manual is also somewhat useless in that they did a 3x3 byte array
so you can't really tell the vertical from the horizontal.

There are many different ways to represent pixels in memory.
The pixels in the bytes can stored horizontally and the pixels can be MSB to LSB or LSB to MSB
or the bytes can be stored vertically with the same bit ordering option.

So you will need to figure out what order the bytes and pixels are needed to be in
for the printer bitmaps and potentially (more than likely) have to remap them
from what you have to match.


It will take some figuring out but once you understand both data formats,
you could then pretty easily construct the pixel bytes on the fly from the XBM pixel data
(or whatever format you have) to the needed bytes for the printer.

--- bill


zonkzonk

hey there,

thanks for the tips, i'll give them a try soon, hopefully tomorrow.
I forgot to post this tutorial yesterday -> http://www.ladyada.net/products/thermalprinter/,
they did a library for the printer.

Byte orientation seems to be horizontal.




bperrybap

The Big/Little endian, referenced doesn't really makes sense for bit ordering, so I assume they
mean LSB to MSB for "little" endian.

It sounds like the byte orientation is horizontal and is LSB to MSB so it matches
the data format of X bitmaps, which means you can directly
use the data created by the .xbm exports from gimp.



--- bill

jeanmat

Hi there,
found this topic as I am trying to do the same as zonkzonk (actually print a QR code on the thermal printer)
thanks bill for your advices, but it looks that .xbm exports from gimp are not what is expected, if you have any further insights, I'd gladly go on with them, or if anyone managed to convert bitmaps to cpp on a mac (using The Gimp or Graphic Converter or...) to use with the arduino...
thanks!
mat

robtillaart


Think it is quite well possible to make even an Arduino program to convert a bmp file to cpp code.

strip of the header and loop through the data - http://en.wikipedia.org/wiki/BMP_file_format -
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

bperrybap


Hi there,
found this topic as I am trying to do the same as zonkzonk (actually print a QR code on the thermal printer)
thanks bill for your advices, but it looks that .xbm exports from gimp are not what is expected, if you have any further insights, I'd gladly go on with them, or if anyone managed to convert bitmaps to cpp on a mac (using The Gimp or Graphic Converter or...) to use with the arduino...
thanks!
mat


".cpp" is not a graphic format. There are many ways that bitmap data can be encoded and stored
into a C data array for compiling and linking into a program image.
Getting the bitmap data into a C data array is really only half the issue.
Gimp takes the bitmap file data and creates a C data array that can be used to compile and link into your
code.
Once the data is stored in the program image you still have to have code to get it
out and then do something with it.
Depending on the format of the data, you may or may not have to massage the data in order to use it.
You will have to look at the format and bit ordering of what you have vs what you need and write
the necessary code to do what ever is necessary.
The massaging of the data can happen up front before it is converted into a C data array
or it can happen run time or be done a bit in each.
It all depends on what you have vs what you need and the tools you are using.


--- bill


Go Up