mirror of https://github.com/MLXXXp/Arduboy2.git
Rewrite Cabi README.md with more details
Also added file sample.png in the cabi directory, which is used for the example sketch in the Cabi README.md file Also added a note referring to Cabi in the documentation for drawCompressed()
This commit is contained in:
parent
566557eab3
commit
c74438e377
|
@ -1,75 +1,203 @@
|
|||
# Cabi
|
||||
Arduboy encoder:
|
||||
Monochrome rle encoding by [Zep @lexaloffle](https://twitter.com/lexaloffle)
|
||||
# Cabi - Compress Arduboy Image
|
||||
|
||||
This tool is used for creating a compressed array from an image (png)
|
||||
A command line program to read a PNG (Portable Network Graphics) file
|
||||
containing a bitmap image, compress it using RLE encoding and convert it to
|
||||
C/C++ code suitable for use with the Team A.R.G. *drawCompressed()* function.
|
||||
This function is included in the Arduboy2 library.
|
||||
|
||||
The function to decompress in Arduino (Arduboy) can be found here:
|
||||
Written by zep
|
||||
|
||||
https://github.com/TEAMarg/drawCompressed
|
||||
https://www.lexaloffle.com/bbs/?uid=1
|
||||
|
||||
to build:
|
||||
```Bash
|
||||
gcc cabi.c lodepng/lodepng.c -o cabi
|
||||
https://twitter.com/lexaloffle
|
||||
|
||||
Contributed to Team A.R.G.
|
||||
|
||||
This program uses code from the LodePNG project by Lode Vandevenne to read
|
||||
and decode PNG files.
|
||||
|
||||
https://github.com/lvandeve/lodepng
|
||||
|
||||
This version of Cabi is maintained as part of the Arduboy2 library so that it
|
||||
remains available since the demise of Team A.R.G.
|
||||
|
||||
## Building the program
|
||||
|
||||
Pre-built executable code is not provided due to the difficulty of maintaining
|
||||
versions for all the many operating systems that it could be run on.
|
||||
|
||||
The code is written in C and should compile properly using any ANSI C99
|
||||
compatible compiler, such as (but not limited to) gcc or clang.
|
||||
|
||||
### Build examples
|
||||
|
||||
To build from a copy of the cabi directory tree provided, while in the base
|
||||
directory containing cabi.c use:
|
||||
|
||||
`gcc cabi.c lodepng/lodepng.c -o cabi`
|
||||
|
||||
or
|
||||
|
||||
`clang cabi.c lodepng/lodepng.c -o cabi`
|
||||
|
||||
|
||||
For Windows, it may be more desirable to name the program `CABI.EXE` by using:
|
||||
|
||||
`-o CABI.EXE`
|
||||
|
||||
Compiler options for optimization, etc. (such as -O2 or -Os) can be added if
|
||||
desired but likely won't make much difference for most uses.
|
||||
|
||||
## Usage
|
||||
|
||||
The binary executable file (cabi or CABI.EXE) should be placed somewhere in the
|
||||
path for executables on the operating system used, or else include the path as
|
||||
part of the command given.
|
||||
|
||||
Running Cabi without any parameters will just output a brief program
|
||||
description and the usage syntax:
|
||||
|
||||
```text
|
||||
cabi - Compress Arduboy Image
|
||||
Convert a PNG file into RLE encoded C/C++ source
|
||||
for use with Arduboy2 drawCompressed()
|
||||
|
||||
usage: cabi in.png [array_name_prefix]
|
||||
```
|
||||
|
||||
to use:
|
||||
```Bash
|
||||
cabi input_file.png [array_name_prefix]
|
||||
```
|
||||
For `in.png` substitute the name of the PNG file to be converted. If the file
|
||||
isn't in the current directory, the full path and name can be specified.
|
||||
|
||||
Look at the compress ratio, before using the compressed data, it might be worse in some cases (above 1 is bad)
|
||||
For `[array_name_prefix]` an optional prefix for the names of the arrays created
|
||||
can be given. If this parameter isn't provided, `compressed_image` will be used
|
||||
for the prefix.
|
||||
|
||||
ouput:
|
||||
```C++
|
||||
// input_file.png width: 128 height: 48
|
||||
const uint8_t PROGMEM array_name_prefix[] = {
|
||||
0x7f,0x2f,0x30,0x68,0xb7,0xdb,0xed,0xdb,0x53,0x9f,0xfa,0x73,0x97,0xbb,0xd5,0xe7,
|
||||
0x2e,0x77,0xb9,0xcb,0x5d,0x6e,0xbb,0xbd,0xdc,0xe5,0x2e,0x77,0xb9,0xcb,0x5d,0xee,
|
||||
0x72,0x97,0x5b,0x2b,0xbb,0xdc,0x6e,0xb7,0xdb,0xed,0x76,0xbb,0xdd,0x6e,0xb7,0xdb,
|
||||
0xed,0x76,0xbb,0xdd,0x6e,0xb7,0xca,0xae,0x43,0x57,0x76,0xbb,0x5d,0x6e,0xb7,0xdb,
|
||||
0xed,0x76,0xbb,0xdd,0x6e,0xb7,0xdb,0xad,0xb2,0xdb,0x75,0xd8,0x5a,0x2a,0xb9,0xdd,
|
||||
0x6e,0xb7,0xeb,0x75,0x74,0xd9,0xe5,0x72,0xf9,0xfd,0xdf,0xea,0x72,0x57,0x77,0x75,
|
||||
0x97,0x3b,0x6d,0x95,0x93,0xca,0x2a,0xbb,0x0e,0xbf,0x6d,0x6f,0x75,0xab,0xed,0xb9,
|
||||
0x5c,0x77,0x2a,0xcf,0x9f,0x76,0xda,0xd5,0xad,0x4e,0xf7,0xaa,0x57,0xe9,0x74,0x3a,
|
||||
0x9d,0xbb,0xa4,0xc2,0xd1,0x76,0xb6,0xb4,0xd3,0x2e,0x9f,0x5e,0x5a,0x85,0xbc,0x74,
|
||||
0x3a,0x9d,0x4e,0xa7,0x3b,0x67,0x57,0x5b,0xaf,0x93,0x4a,0xb9,0x9d,0x52,0xca,0x2d,
|
||||
0x97,0xdb,0x74,0x6c,0x49,0xe5,0x9c,0x92,0x4a,0x2a,0xa9,0xa4,0x53,0x84,0xe9,0xf4,
|
||||
0xea,0x53,0xbf,0x56,0x2a,0x65,0xed,0x6e,0xa7,0x94,0x52,0x4a,0x46,0x9f,0x5e,0xaf,
|
||||
0x97,0xcb,0x6d,0xbc,0x4b,0xe7,0x5c,0xff,0x13,0x7a,0x9f,0xde,0xce,0xbe,0xd6,0xb9,
|
||||
0xee,0xd4,0xae,0x3b,0xb5,0x6e,0x7b,0xab,0x5b,0x8d,0x24,0x25,0x4b,0x29,0x95,0x4a,
|
||||
0x76,0x56,0x3a,0x1d,0xdb,0xce,0xcd,0x96,0x4e,0xa7,0xd3,0xe9,0xec,0x4e,0x4a,0xe9,
|
||||
0xec,0x08,0xdb,0x3a,0x67,0xe7,0x52,0xb3,0x29,0x2d,0xf5,0xa8,0x4b,0xa7,0xd3,0xe9,
|
||||
0x74,0xce,0xb9,0x5b,0x2f,0xdd,0x6a,0x87,0xac,0xa4,0x2a,0x25,0x95,0x54,0x52,0x49,
|
||||
0x25,0xed,0x36,0xa4,0xed,0xdc,0x64,0x49,0xa5,0x64,0xc8,0x5a,0x2a,0x1d,0xda,0xc2,
|
||||
0x1b,0x11,0x06,0xb9,0x2a,0x95,0x4c,0x55,0x2a,0xa2,0xc6,0xd5,0xea,0x56,0xb7,0xdd,
|
||||
0x6e,0xb7,0x4a,0x4a,0x55,0xa5,0x2a,0x95,0x52,0x2a,0x55,0xc9,0x54,0xaa,0x92,0xa9,
|
||||
0x54,0x25,0x53,0x29,0xa5,0xdd,0xf4,0x69,0x25,0xa5,0x54,0xed,0x5c,0xe7,0x3a,0xe7,
|
||||
0x9c,0x73,0x4a,0x2a,0x3b,0x15,0x51,0x52,0xf1,0x79,0xa5,0xd3,0x49,0x25,0x95,0xdc,
|
||||
0x6e,0xb7,0xdb,0xed,0x36,0x9d,0xce,0x6e,0xff,0xff,0xd3,0xa7,0x75,0x3a,0x1d,0xd9,
|
||||
0xce,0x39,0xe7,0x1c,0xd3,0xce,0x39,0xe7,0x9c,0xeb,0x5c,0xe7,0x9c,0x73,0x6e,0xf2,
|
||||
0xa4,0x54,0x52,0x2a,0xbb,0xdd,0x6e,0x2f,0xad,0xb4,0xd2,0xf9,0xb4,0x72,0x4e,0x6e,
|
||||
0x63,0x95,0xce,0x39,0xa9,0x3e,0xf5,0x6f,0x8f,0x08,0x87,0x64,0xc9,0x54,0x32,0xa2,
|
||||
0xb6,0xdb,0xed,0xea,0x56,0xb7,0x3d,0x9d,0x4e,0xa7,0x5b,0x5d,0x77,0x4a,0xb9,0xfe,
|
||||
0xa7,0x4a,0xd6,0xd2,0x29,0xd5,0x5d,0xab,0x63,0xeb,0x55,0xaf,0xf2,0x4a,0x72,0xef,
|
||||
0xdc,0x76,0xbb,0x5d,0x6e,0xb7,0x4a,0x2a,0xe7,0x56,0x3b,0x19,0xd1,0x76,0x2e,0x65,
|
||||
0xb7,0xdb,0xd5,0xbd,0xea,0x5c,0xe7,0x3a,0x9d,0xdd,0x6e,0xb7,0x5b,0x25,0x9d,0xb3,
|
||||
0xe9,0x94,0x54,0x52,0x49,0x25,0x95,0x54,0xaa,0x94,0x2a,0x25,0x95,0x54,0xd2,0x59,
|
||||
0x75,0xdb,0xed,0xae,0x5e,0x75,0xae,0x73,0x9d,0xeb,0xd4,0xa7,0x3e,0xf5,0xb9,0xda,
|
||||
0xee,0xa4,0xb4,0xca,0x6e,0xb7,0xdb,0xad,0x73,0xee,0xda,0x39,0xbb,0xba,0xb7,0x53,
|
||||
0x25,0x95,0xdc,0x2e,0x95,0x53,0xf6,0x72,0x97,0x93,0x4a,0x3a,0xa9,0xa4,0x3a,0xa5,
|
||||
0x7a,0x95,0xfa,0x5c,0xa7,0xd3,0x69,0xae,0xed,0x2a,0xa9,0x64,0x25,0x95,0x4e,0xa7,
|
||||
0xd3,0xe9,0xd0,0x97,0x5e,0x67,0xb7,0xa1,0x69,0x9d,0x1d,0xcb,0xe9,0xed,0x36,0x34,
|
||||
0xea,0x74,0x3a,0x9d,0x56,0x4a,0x2a,0xa9,0x94,0x4e,0xa7,0x53,0x44,0x4a,0x56,0xa9,
|
||||
0xaa,0x54,0x2a,0x25,0x75,0x5a,0x6d,0x95,0x74,0xeb,0x74,0xe7,0x8a,0x4a,0xc9,0x2a,
|
||||
0x55,0x95,0x4a,0xa5,0xa4,0x56,0xd2,0x39,0xe7,0xb6,0xdb,0xed,0xf6,0xed,0x29,0x59,
|
||||
0xc9,0x4a,0x2a,0xe2,0x74,0xb4,0xe9,0xd0,0xb5,0xce,0x8e,0xfd,0x74,0x3a,0xb4,0x01
|
||||
If the program is unable to produce proper output, an error message will be
|
||||
given and a non-zero exit code will be returned.
|
||||
|
||||
## Input file decoding
|
||||
|
||||
The input file should be a PNG file containing the image to be converted. The
|
||||
image will be translated to a raw array of 32 bit RGBA (Red, Green, Blue, Alpha)
|
||||
pixels internally before being processed to output. Ideally, pixels that are to
|
||||
be drawn (represented as a 1 in the image output) should be fully white.
|
||||
Non-drawn (0) pixels should be fully black. Pixels intended to be masked out of
|
||||
the image (represented as a 0 in both the image and mask output), should be
|
||||
fully transparent and their color doesn't matter.
|
||||
|
||||
However, after translation to RGBA, any pixel with an alpha (opaqueness) value
|
||||
of 127 or less will be set as non-drawn (0) for both the image and the mask.
|
||||
For the image, after the alpha value is first taken into account, pixels with a
|
||||
red color value greater than 127 will be set as drawn (1) and others will be
|
||||
set as non-drawn (0). For the mask, only the alpha value is used and red is
|
||||
ignored. Green and blue color values are ignored for both image and mask.
|
||||
|
||||
### To summarize:
|
||||
|
||||
For the image:
|
||||
|
||||
Green and blue are ignored.
|
||||
|
||||
| Alpha | Red | Output |
|
||||
|:------:|:-------:|:------:|
|
||||
| <= 127 | <= 127 | 0 |
|
||||
| <= 127 | > 127 | 0 |
|
||||
| > 127 | <= 127 | 0 |
|
||||
| > 127 | > 127 | 1 |
|
||||
|
||||
For the mask:
|
||||
|
||||
Red, green and blue are ignored.
|
||||
|
||||
| Alpha | Output |
|
||||
|:------:|:------:|
|
||||
| <= 127 | 0 |
|
||||
| > 127 | 1 |
|
||||
|
||||
## Output
|
||||
|
||||
Cabi will send all output to `stdout`, which is usually the console unless
|
||||
redirected. To save the output, you may be able to copy and paste it into your
|
||||
editor, or you can redirect `stdout` to a file for importing. For example:
|
||||
|
||||
`cabi PlayerSprite.png PlayerSprite > PlayerSprite.out`
|
||||
|
||||
If conversion is successful, the output will be text representing C/C++ code
|
||||
for two arrays, an image and a mask, that can be included in a sketch for use
|
||||
by the *drawCompressed()* function. The image array will be named the same as
|
||||
the prefix. The mask name will be the prefix with `_mask` appended to it.
|
||||
|
||||
Along with the actual array text, a comment will be included before each array
|
||||
giving the input file name used and the dimensions of the image. A comment
|
||||
included after each array will give the size of the array and the compression
|
||||
ratio compared to the non-compressed equivalent (although the ratio is based
|
||||
on the compressed array including two bytes for the bitmap dimensions compared
|
||||
to a non-compressed array without bitmap dimensions).
|
||||
|
||||
Note that it's possible that the "compressed" array will actually end up
|
||||
larger than the equivalent non-compressed one would. This is indicated by
|
||||
a compression ratio greater than 1. The ratio should be noted and taken into
|
||||
account when determining whether using Cabi compressed bitmaps is suitable for
|
||||
the intended purpose.
|
||||
|
||||
If masking isn't required, the mask array can be ignored or deleted.
|
||||
|
||||
Note that the usage message or any error message will also be sent to `stdout`,
|
||||
rather than `stderr`. Therefore, if you redirect the output to a file, in this
|
||||
case the file will contain only that text.
|
||||
|
||||
## Using the output with *drawCompressed()*
|
||||
|
||||
The Arduboy2 *drawCompressed()* function doesn't natively handle a mask for
|
||||
"transparent" pixels in an image. However, masking can be accomplished by
|
||||
calling *drawCompressed()* twice with the same coordinates. The first call
|
||||
specifies the mask array and the color BLACK. The second call specifies the
|
||||
image array and the color WHITE.
|
||||
|
||||
An example PNG bitmap named `sample.png` is included with the program. Here is
|
||||
an example Arduboy sketch that draws this bitmap with masking, using the Cabi
|
||||
output imported into the sketch.
|
||||
|
||||
```cpp
|
||||
#include <Arduboy2.h>
|
||||
|
||||
Arduboy2 arduboy;
|
||||
|
||||
// ===== Cabi output =====
|
||||
// sample.png width: 32 height: 32
|
||||
const PROGMEM uint8_t sample[] = {
|
||||
0x1f,0x1f,0x68,0x93,0xca,0x39,0xe5,0x9c,0x72,0xca,0xe9,0x74,0x4b,0x25,0x95,0xdc,
|
||||
0x6e,0xb7,0xdb,0xed,0x56,0x49,0x65,0xb7,0x4a,0x3a,0xa9,0xac,0x92,0x4e,0x3a,0xa9,
|
||||
0x74,0x94,0x8c,0x6a,0xbb,0xdd,0x6e,0xb7,0x8c,0x76,0xbb,0xdd,0x6e,0xb7,0xdb,0xed,
|
||||
0x76,0xbb,0xdd,0xf2,0xf1,0xa6,0xb7,0x52,0x79,0xc5,0xa4,0xbc,0x92,0x76,0x1d,0x2f,
|
||||
0x9f,0xdd,0x6e,0xb7,0xdb,0xed,0x76,0xbb,0xdd,0x6e,0xb7,0x8c,0xf4,0xd9,0x15,0x23,
|
||||
0x65,0x5a,0x49,0x27,0x9d,0x54,0x56,0x49,0x27,0x95,0xdd,0x2a,0xa9,0xec,0x76,0xbb,
|
||||
0xdd,0x6e,0x97,0x4a,0x2a,0xb9,0x54,0xce,0x39,0xe5,0x94,0x73,0xca,0x39,0x25,0xa3,
|
||||
0x05
|
||||
};
|
||||
// bytes:640 ratio: 0.833
|
||||
// bytes:113 ratio: 0.883
|
||||
|
||||
|
||||
const uint8_t PROGMEM array_name_prefix_mask[] = {
|
||||
0x7f,0x2f,0x81,0xff,0x17
|
||||
const PROGMEM uint8_t sample_mask[] = {
|
||||
0x1f,0x1f,0x68,0x93,0xca,0x39,0x25,0x95,0xdc,0xa6,0xd3,0xa1,0x35,0x9d,0x4e,0x6f,
|
||||
0x95,0x54,0xd2,0x39,0xa9,0x74,0x94,0xe8,0xb4,0xdb,0xed,0x76,0xbb,0xdd,0x6e,0xb7,
|
||||
0xdb,0xed,0x16,0x8f,0x8a,0x49,0xe1,0xd1,0x6e,0xb7,0xdb,0xed,0x76,0xbb,0xdd,0x6e,
|
||||
0xb7,0x5b,0x74,0x52,0xa6,0x95,0x74,0x4e,0x2a,0xa9,0xec,0x3a,0x9d,0x0e,0xad,0xe9,
|
||||
0x74,0x76,0xa9,0xa4,0x72,0x4e,0xc9,0x68,0x01
|
||||
};
|
||||
// bytes:5 ratio: 0.007
|
||||
// bytes:73 ratio: 0.570
|
||||
// =======================
|
||||
|
||||
void setup() {
|
||||
arduboy.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
arduboy.clear();
|
||||
|
||||
arduboy.drawCompressed(20, 10, sample_mask, BLACK);
|
||||
arduboy.drawCompressed(20, 10, sample, WHITE);
|
||||
|
||||
arduboy.display();
|
||||
}
|
||||
```
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 280 B |
|
@ -700,14 +700,19 @@ class Arduboy2Base : public Arduboy2Core
|
|||
* (optional; defaults to WHITE).
|
||||
*
|
||||
* \details
|
||||
* Draw a bitmap starting at the given coordinates from an array that has
|
||||
* been compressed using an algorthm implemented by Team A.R.G.
|
||||
* Draw a bitmap starting at the given coordinates using an array that has
|
||||
* been compressed using an RLE algorthm implemented by Team A.R.G.
|
||||
*
|
||||
* Bits set to 1 in the provided bitmap array will have their corresponding
|
||||
* pixel set to the specified color. For bits set to 0 in the array, the
|
||||
* corresponding pixel will be left unchanged.
|
||||
* Bits set to 1 in the provided bitmap array (after decoding) will have
|
||||
* their corresponding pixel set to the specified color. For bits set to 0
|
||||
* in the array, the corresponding pixel will be left unchanged.
|
||||
*
|
||||
* The array must be located in program memory by using the PROGMEM modifier.
|
||||
*
|
||||
* \note
|
||||
* C source code for a command line program named `Cabi`, which can convert
|
||||
* a PNG bitmap image file to source code suitable for use with
|
||||
* `drawCompressed()`, is included in the `extras` directory of the library.
|
||||
*/
|
||||
static void drawCompressed(int16_t sx, int16_t sy, const uint8_t *bitmap, uint8_t color = WHITE);
|
||||
|
||||
|
|
Loading…
Reference in New Issue