369 lines
13 KiB
C
369 lines
13 KiB
C
|
#ifndef MICROBIT_IMAGE_H
|
||
|
#define MICROBIT_IMAGE_H
|
||
|
|
||
|
#include "mbed.h"
|
||
|
|
||
|
/**
|
||
|
* Class definition for a MicroBitImage.
|
||
|
*
|
||
|
* An MicroBitImage is a simple bitmap representation of an image.
|
||
|
* n.b. This is a mutable, managed type.
|
||
|
*/
|
||
|
class MicroBitImage
|
||
|
{
|
||
|
int16_t width; // Width of the bitmap, in pixels.
|
||
|
int16_t height; // Height of the bitmap, in pixels.
|
||
|
int16_t *ref; // Reference count.
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Internal constructor which provides sanity checking and initialises class properties.
|
||
|
*
|
||
|
* @param x the width of the image
|
||
|
* @param y the height of the image
|
||
|
* @param bitmap an array of integers that make up an image.
|
||
|
*/
|
||
|
void init(const int16_t x, const int16_t y, const uint8_t *bitmap);
|
||
|
|
||
|
/**
|
||
|
* Internal constructor which defaults to the Empty Image instance variable
|
||
|
*/
|
||
|
void init_empty();
|
||
|
|
||
|
public:
|
||
|
static MicroBitImage EmptyImage; // Shared representation of a null image.
|
||
|
uint8_t *bitmap; // 2D array representing the bitmap image.
|
||
|
|
||
|
/**
|
||
|
* Default Constructor.
|
||
|
* Creates a new reference to the empty MicroBitImage bitmap
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* MicroBitImage i(); //an empty image
|
||
|
* @endcode
|
||
|
*/
|
||
|
MicroBitImage();
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Copy Constructor.
|
||
|
* Add ourselves as a reference to an existing MicroBitImage.
|
||
|
*
|
||
|
* @param image The MicroBitImage to reference.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* MicroBitImage i("0,1,0,1,0\n");
|
||
|
* MicroBitImage i2(i); //points to i
|
||
|
* @endcode
|
||
|
*/
|
||
|
MicroBitImage(const MicroBitImage &image);
|
||
|
|
||
|
/**
|
||
|
* Constructor.
|
||
|
* Create a blank bitmap representation of a given size.
|
||
|
*
|
||
|
* @param s A text based representation of the image given whitespace delimited numeric values.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
|
||
|
* @endcode
|
||
|
*/
|
||
|
explicit MicroBitImage(const char *s);
|
||
|
|
||
|
/**
|
||
|
* Constructor.
|
||
|
* Create a blank bitmap representation of a given size.
|
||
|
*
|
||
|
* @param x the width of the image.
|
||
|
* @param y the height of the image.
|
||
|
*
|
||
|
* Bitmap buffer is linear, with 8 bits per pixel, row by row,
|
||
|
* top to bottom with no word alignment. Stride is therefore the image width in pixels.
|
||
|
* in where w and h are width and height respectively, the layout is therefore:
|
||
|
*
|
||
|
* |[0,0]...[w,o][1,0]...[w,1] ... [[w,h]
|
||
|
*
|
||
|
* A copy of the image is made in RAM, as images are mutable.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* MicroBitImage i(5,5); // a blank 5x5 image
|
||
|
* @endcode
|
||
|
*/
|
||
|
MicroBitImage(const int16_t x, const int16_t y);
|
||
|
|
||
|
/**
|
||
|
* Constructor.
|
||
|
* Create a bitmap representation of a given size, based on a given buffer.
|
||
|
*
|
||
|
* @param x the width of the image.
|
||
|
* @param y the height of the image.
|
||
|
* @param bitmap a 2D array representing the image.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart);
|
||
|
* @endcode
|
||
|
*/
|
||
|
MicroBitImage(const int16_t x, const int16_t y, const uint8_t *bitmap);
|
||
|
|
||
|
/**
|
||
|
* Destructor.
|
||
|
* Removes buffer resources held by the instance.
|
||
|
*/
|
||
|
~MicroBitImage();
|
||
|
|
||
|
/**
|
||
|
* Copy assign operation.
|
||
|
*
|
||
|
* Called when one MicroBitImage is assigned the value of another using the '=' operator.
|
||
|
* Decrement our reference count and free up the buffer as necessary.
|
||
|
* Then, update our buffer to refer to that of the supplied MicroBitImage,
|
||
|
* and increase its reference count.
|
||
|
*
|
||
|
* @param s The MicroBitImage to reference.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart);
|
||
|
* MicroBitImage i1();
|
||
|
* i1 = 1; // i1 now references i
|
||
|
* @endcode
|
||
|
*/
|
||
|
MicroBitImage& operator = (const MicroBitImage& i);
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Equality operation.
|
||
|
*
|
||
|
* Called when one MicroBitImage is tested to be equal to another using the '==' operator.
|
||
|
*
|
||
|
* @param i The MicroBitImage to test ourselves against.
|
||
|
* @return true if this MicroBitImage is identical to the one supplied, false otherwise.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* MicroBitImage i();
|
||
|
* MicroBitImage i1();
|
||
|
*
|
||
|
* if(i == i1) //will be true
|
||
|
* print("true");
|
||
|
* @endcode
|
||
|
*/
|
||
|
bool operator== (const MicroBitImage& i);
|
||
|
|
||
|
/**
|
||
|
* Clears all pixels in this image
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
|
||
|
* i.clear();
|
||
|
* @endcode
|
||
|
*/
|
||
|
void clear();
|
||
|
|
||
|
/**
|
||
|
* Sets the pixel at the given co-ordinates to a given value.
|
||
|
* @param x The co-ordinate of the pixel to change w.r.t. top left origin.
|
||
|
* @param y The co-ordinate of the pixel to change w.r.t. top left origin.
|
||
|
* @param value The new value of the pixel (the brightness level 0-255)
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
|
||
|
* i.setPixelValue(0,0,255);
|
||
|
* @endcode
|
||
|
*/
|
||
|
void setPixelValue(int16_t x , int16_t y, uint8_t value);
|
||
|
|
||
|
/**
|
||
|
* Determines the value of a given pixel.
|
||
|
* @return The value assigned to the given pixel location (the brightness level 0-255)
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image
|
||
|
* i.getPixelValue(0,0); //should be 0;
|
||
|
* @endcode
|
||
|
*/
|
||
|
int getPixelValue(int16_t x , int16_t y);
|
||
|
|
||
|
/**
|
||
|
* Replaces the content of this image with that of a given
|
||
|
* 2D array representing the image.
|
||
|
* Origin is in the top left corner of the image.
|
||
|
*
|
||
|
* @param x the width of the image.
|
||
|
* @param y the height of the image.
|
||
|
* @param bitmap a 2D array representing the image.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i();
|
||
|
* i.printImage(0,0,heart);
|
||
|
* @endcode
|
||
|
*/
|
||
|
void printImage(int16_t x, int16_t y, const uint8_t *bitmap);
|
||
|
|
||
|
/**
|
||
|
* Pastes a given bitmap at the given co-ordinates.
|
||
|
* Any pixels in the relvant area of this image are replaced.
|
||
|
*
|
||
|
* @param image The MicroBitImage to paste.
|
||
|
* @param x The leftmost X co-ordinate in this image where the given image should be pasted.
|
||
|
* @param y The uppermost Y co-ordinate in this image where the given image should be pasted.
|
||
|
* @param alpha set to 1 if transparency clear pixels in given image should be treated as transparent. Set to 0 otherwise.
|
||
|
* @return The number of pixels written.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart); //if you show this image - you will see a big heart
|
||
|
* i.paste(-5,0,i); //displays a small heart :)
|
||
|
* @endcode
|
||
|
*/
|
||
|
int paste(const MicroBitImage &image, int16_t x, int16_t y, uint8_t alpha);
|
||
|
|
||
|
/**
|
||
|
* Prints a character to the display at the given location
|
||
|
*
|
||
|
* @param c The character to display.
|
||
|
* @param x The x co-ordinate of on the image to place the top left of the character
|
||
|
* @param y The y co-ordinate of on the image to place the top left of the character
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* MicroBitImage i(5,5);
|
||
|
* i.print('a',0,0);
|
||
|
* @endcode
|
||
|
*/
|
||
|
void print(char c, int16_t x, int16_t y);
|
||
|
|
||
|
/**
|
||
|
* Shifts the pixels in this Image a given number of pixels to the Left.
|
||
|
*
|
||
|
* @param n The number of pixels to shift.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart); //if you show this image - you will see a big heart
|
||
|
* i.shiftLeft(5); //displays a small heart :)
|
||
|
* @endcode
|
||
|
*/
|
||
|
void shiftLeft(int16_t n);
|
||
|
|
||
|
/**
|
||
|
* Shifts the pixels in this Image a given number of pixels to the Right.
|
||
|
*
|
||
|
* @param n The number of pixels to shift.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart);
|
||
|
* i.shiftLeft(5); //displays a small heart :)
|
||
|
* i.shiftRight(5); //displays a big heart :)
|
||
|
* @endcode
|
||
|
*/
|
||
|
void shiftRight(int16_t n);
|
||
|
|
||
|
/**
|
||
|
* Shifts the pixels in this Image a given number of pixels to Upward.
|
||
|
*
|
||
|
* @param n The number of pixels to shift.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart);
|
||
|
* i.shiftUp(1);
|
||
|
* @endcode
|
||
|
*/
|
||
|
void shiftUp(int16_t n);
|
||
|
|
||
|
/**
|
||
|
* Shifts the pixels in this Image a given number of pixels to Downward.
|
||
|
*
|
||
|
* @param n The number of pixels to shift.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart);
|
||
|
* i.shiftDown(1);
|
||
|
* @endcode
|
||
|
*/
|
||
|
void shiftDown(int16_t n);
|
||
|
|
||
|
/**
|
||
|
* Gets the width of this image.
|
||
|
*
|
||
|
* @return The width of this image.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart);
|
||
|
* i.getWidth(); //equals 10...
|
||
|
* @endcode
|
||
|
*/
|
||
|
int getWidth();
|
||
|
|
||
|
/**
|
||
|
* Gets the height of this image.
|
||
|
*
|
||
|
* @return The height of this image.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart);
|
||
|
* i.getHeight(); //equals 5...
|
||
|
* @endcode
|
||
|
*/
|
||
|
int getHeight();
|
||
|
|
||
|
/**
|
||
|
* Converts the bitmap to a csv string.
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart);
|
||
|
* uBit.serial.printString(i.toString()); // "0,1,0,1,0,0,0,0,0,0\n..."
|
||
|
* @endcode
|
||
|
*/
|
||
|
ManagedString toString();
|
||
|
|
||
|
/**
|
||
|
* Crops the image to the given dimensions
|
||
|
*
|
||
|
* @param startx the location to start the crop in the x-axis
|
||
|
* @param starty the location to start the crop in the y-axis
|
||
|
* @param width the width of the desired cropped region
|
||
|
* @param height the height of the desired cropped region
|
||
|
*
|
||
|
* @return an instance of MicroBitImage with your cropped region
|
||
|
*
|
||
|
* Example:
|
||
|
* @code
|
||
|
* const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart
|
||
|
* MicroBitImage i(10,5,heart);
|
||
|
* uBit.serial.printImage(i.crop(0,0,2,2)); // "0,1\n1,1\n"
|
||
|
* @endcode
|
||
|
*/
|
||
|
MicroBitImage crop(int startx, int starty, int finx, int finy);
|
||
|
|
||
|
};
|
||
|
|
||
|
#endif
|
||
|
|