GBImg

Creations

AceyT

6 years ago

Introduction

GBImg is a command-line tool that allow you to convert BMP and PNG images into the Gamebuino flash memory format.

It can also handle animated images and spritesheets

It currently support only uint8_t[] flash images in the indexed mode


Usage:
  GBImg [OPTION...]

  -o, --output-path arg         File name of the export (default: code.hpp)
  -i, --image-input arg         Image path to convert
  -c, --code-name arg           identifier in the exported code (default:
                                image)
      --transparency [=N(=0)]   Choosen color index used for transparency.
                                Value greater than 15 (0x0F) will make the
                                program not handle transparency (default: 255)
      --palette default / edge16
                                Choosen color palette used for finding
                                correct indexes (default: default)
      --palette-file arg        File from which the color palette will be
                                used (override palette option)
  -h, --help                    Print the help

 Spritesheet options:
  -s, --spritesheet  Activate the spritesheets mode
      --tile-x N     Number of tiles on X axis Sub width will be deduced
                     with image-width / tile-x (default: 0)
      --tile-y N     Number of tiles on Y axis | Sub height will be deduced
                     with image-height / tile-y (default: 0)
      --framerate N  Framerate of the animation | number of frame per
                     animation (default: 0)


The download link provide a compiled version for Windows 7 and some test / example in bat files


Todo

  • Loading custom color palette from file
  • Support for uint16_t[] images
  • Convert RGB888 to RGB565
  • Multiples images at once
  • Other export methods

View full creation

Sorunome

NEW 6 years ago

Just asking, i didn't check the source / try but the web-tool has this bug:

on indexed images with an odd width you are supposed to pad the last nibble so that each row is always a whole number of bytes

AceyT

NEW 6 years ago

Well, I'm not sure of what you mean by asking if I "pad the last nibble" on odd-width indexed image.
In my understanding, padding is adding extra byte correct ? 'Cause that's what I'm doing.

According to tests I've done with my Gamebuino, I've decided to let an extra nibble if the width is odd, because it work as expected when the image is rendered. For example, if I take this french flag with 3x3 pixels, my program will allocate 4x3 memory with the formula [height  * (width+1)/2].


And the outputted code will be :

const uint8_t imageData[] = {
3,3,
0,0,0,
0xFF,
1,

0xFD,0x40,
0xFD,0x40,
0xFD,0x40
};
Image image = Image(imageData);
//index numbers are from edge16 palette

Sorunome

6 years ago

Okay, then you are doing it the correct way, great!


EDIT: i'd recommend using `Image myimg(imgdata);` instead of `Image myimg = Image(imgdata);`

Sorunome

NEW 6 years ago

AceyT AceyT

Okay, then you are doing it the correct way, great!


EDIT: i'd recommend using `Image myimg(imgdata);` instead of `Image myimg = Image(imgdata);`

AceyT

6 years ago

Okay, I'll make the change and commit it :)

EDIT : change made and updated the compiled version

Aurélien Rodot

6 years ago

Hey, would you mind explaining why quickly or share a link to the reason why ? I would have used the same syntax as AceyT ^^

AceyT

NEW 6 years ago

Sorunome Sorunome

Okay, I'll make the change and commit it :)

EDIT : change made and updated the compiled version

Aurélien Rodot

NEW 6 years ago

Sorunome Sorunome

Hey, would you mind explaining why quickly or share a link to the reason why ? I would have used the same syntax as AceyT ^^

Sorunome

6 years ago

Let's break `Image img = Image(blah);` down.

So, what happens here first is that a temporary Image is created, with the `Image(blah);` call. Afterwards a new Image called `img` is created. Next, the temporary Image is been copied over to img, calling the copyconstructor.

When you use `Image img(blah);` it just creates a new image img and initializes it with blah


Sorunome

NEW 6 years ago

Aurélien Rodot Aurélien Rodot

Let's break `Image img = Image(blah);` down.

So, what happens here first is that a temporary Image is created, with the `Image(blah);` call. Afterwards a new Image called `img` is created. Next, the temporary Image is been copied over to img, calling the copyconstructor.

When you use `Image img(blah);` it just creates a new image img and initializes it with blah


AceyT

6 years ago

Theoretically, I would said the same as you, but after some tests on my computers and gamebuino, I got other results.

I don't know if this is a compiler optimization or the standard way of interpreting it in C++, but the syntax `Image img = Image(data);` still call the appropriate constructor, and not a constructor + copy constructor;

EDIT : It would appear to be an authorized optimization. It's kind of like Return Value Optimization but named in this case " Copy Elision (cpp reference) ".
So indeed, for clarity && to avoid surprise, it's better to do a direct initialization. There's so many things that you can think about in C++

AceyT

NEW 6 years ago

Sorunome Sorunome

Theoretically, I would said the same as you, but after some tests on my computers and gamebuino, I got other results.

I don't know if this is a compiler optimization or the standard way of interpreting it in C++, but the syntax `Image img = Image(data);` still call the appropriate constructor, and not a constructor + copy constructor;

EDIT : It would appear to be an authorized optimization. It's kind of like Return Value Optimization but named in this case " Copy Elision (cpp reference) ".
So indeed, for clarity && to avoid surprise, it's better to do a direct initialization. There's so many things that you can think about in C++

Sorunome

6 years ago

It would appear to be an authorized optimization

Yeah, compiler optimizes it, except if you turn off optimizations

So indeed, for clarity && to avoid surprise, it's better to do a direct initialization

Yep!


Also, direct initialization is shorter to type xP

Sorunome

NEW 6 years ago

AceyT AceyT

It would appear to be an authorized optimization

Yeah, compiler optimizes it, except if you turn off optimizations

So indeed, for clarity && to avoid surprise, it's better to do a direct initialization

Yep!


Also, direct initialization is shorter to type xP