Demonstration of the Bitmap rendering - reads BMP and JPG files in many format variants and renders to the screen.
Dependencies: FlashFileSystem mbed RA8875
Bitmap and JPEG Demo
This demo publishes each graphic file from a list of files to the display. The graphic files can be BMP, JPG, or ICO. On the terminal it displays the filename and the return-code (in case of an error). This demo works as intended on the 480x272 display in either 8 or 16 bit per pixel mode and it should work on larger displays.
Items of interest to change and rebuild/test:
// Not all systems have the LocalFileSystem. Plug in the library and driver for yours. LocalFileSystem local("local"); // Image source TestImage_T TestImage[] = { { 0, 0, "/local/01601602.bmp"}, { 0, 0, "/local/48027202.bmp"}, { 0, 0, "/local/48027204.bmp"}, { 0, 0, "/local/48027208.bmp"}, { 0, 0, "/local/48027224.bmp"}, { 0, 0, "/local/p480272.jpg"}, { 0, 0, "/local/p480272.bmp"} }; // deefine your screen size and color depth. #define SCREEN_W 480 #define SCREEN_H 272 #define SCREEN_BPP 16
LocalFileSystem may need to be altered to SDFileSystem (for example) and the corresponding paths in the TestImage array.
Also, the Screen size and bit per pixel color depth.
Images
The following image files are saved in different resolution and color depth. The first, and smallest, was simply for developing the monochrome support. Others are 4-bit color, 8-bit color, 24-bit color, and a mislabeled 1-bit color (shown as 02).
/media/uploads/WiredHome/testimages.zip
main.cpp@13:5c69f3c304c8, 2016-05-17 (annotated)
- Committer:
- WiredHome
- Date:
- Tue May 17 22:33:54 2016 +0000
- Revision:
- 13:5c69f3c304c8
- Parent:
- 12:93adb3470150
- Child:
- 14:694822610507
Revised demo to also show JPEG files, not just BMP files.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
WiredHome | 0:9ecf49d75058 | 1 | // ______________ ______________ ______________ _______________ |
WiredHome | 0:9ecf49d75058 | 2 | // /_____ _____/ / ___________/ / ___________/ /_____ ______/ |
WiredHome | 0:9ecf49d75058 | 3 | // / / / / / / / / |
WiredHome | 0:9ecf49d75058 | 4 | // / / / /___ / /__________ / / |
WiredHome | 0:9ecf49d75058 | 5 | // / / / ____/ /__________ / / / |
WiredHome | 0:9ecf49d75058 | 6 | // / / / / / / / / |
WiredHome | 0:9ecf49d75058 | 7 | // / / / /__________ ___________/ / / / |
WiredHome | 0:9ecf49d75058 | 8 | // /__/ /_____________/ /_____________/ /__/ |
WiredHome | 0:9ecf49d75058 | 9 | // |
WiredHome | 0:9ecf49d75058 | 10 | |
WiredHome | 0:9ecf49d75058 | 11 | #include "mbed.h" // v118 |
WiredHome | 0:9ecf49d75058 | 12 | #include "RA8875.h" // v111 |
WiredHome | 0:9ecf49d75058 | 13 | #include "WebColors.h" |
WiredHome | 0:9ecf49d75058 | 14 | #include <algorithm> |
WiredHome | 0:9ecf49d75058 | 15 | |
WiredHome | 1:84fb3e9adaaf | 16 | #define JPEG_TEST |
WiredHome | 1:84fb3e9adaaf | 17 | |
WiredHome | 12:93adb3470150 | 18 | //#define DEBUG "Main" |
WiredHome | 1:84fb3e9adaaf | 19 | // ... |
WiredHome | 1:84fb3e9adaaf | 20 | // INFO("Stuff to show %d", var); // new-line is automatically appended |
WiredHome | 1:84fb3e9adaaf | 21 | // |
WiredHome | 1:84fb3e9adaaf | 22 | #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) |
WiredHome | 1:84fb3e9adaaf | 23 | #define INFO(x, ...) std::printf("[INF %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); |
WiredHome | 1:84fb3e9adaaf | 24 | #define WARN(x, ...) std::printf("[WRN %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); |
WiredHome | 1:84fb3e9adaaf | 25 | #define ERR(x, ...) std::printf("[ERR %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); |
WiredHome | 1:84fb3e9adaaf | 26 | static void HexDump(const char * title, const uint8_t * p, int count) |
WiredHome | 1:84fb3e9adaaf | 27 | { |
WiredHome | 1:84fb3e9adaaf | 28 | int i; |
WiredHome | 1:84fb3e9adaaf | 29 | char buf[100] = "0000: "; |
WiredHome | 1:84fb3e9adaaf | 30 | |
WiredHome | 1:84fb3e9adaaf | 31 | if (*title) |
WiredHome | 1:84fb3e9adaaf | 32 | INFO("%s", title); |
WiredHome | 1:84fb3e9adaaf | 33 | for (i=0; i<count; ) { |
WiredHome | 1:84fb3e9adaaf | 34 | sprintf(buf + strlen(buf), "%02X ", *(p+i)); |
WiredHome | 1:84fb3e9adaaf | 35 | if ((++i & 0x0F) == 0x00) { |
WiredHome | 1:84fb3e9adaaf | 36 | INFO("%s", buf); |
WiredHome | 1:84fb3e9adaaf | 37 | if (i < count) |
WiredHome | 1:84fb3e9adaaf | 38 | sprintf(buf, "%04X: ", i); |
WiredHome | 1:84fb3e9adaaf | 39 | else |
WiredHome | 1:84fb3e9adaaf | 40 | buf[0] = '\0'; |
WiredHome | 1:84fb3e9adaaf | 41 | } |
WiredHome | 1:84fb3e9adaaf | 42 | } |
WiredHome | 1:84fb3e9adaaf | 43 | if (strlen(buf)) |
WiredHome | 1:84fb3e9adaaf | 44 | INFO("%s", buf); |
WiredHome | 1:84fb3e9adaaf | 45 | } |
WiredHome | 1:84fb3e9adaaf | 46 | #else |
WiredHome | 1:84fb3e9adaaf | 47 | #define INFO(x, ...) |
WiredHome | 1:84fb3e9adaaf | 48 | #define WARN(x, ...) |
WiredHome | 1:84fb3e9adaaf | 49 | #define ERR(x, ...) |
WiredHome | 1:84fb3e9adaaf | 50 | #define HexDump(a, b, c) |
WiredHome | 1:84fb3e9adaaf | 51 | #endif |
WiredHome | 0:9ecf49d75058 | 52 | |
WiredHome | 0:9ecf49d75058 | 53 | RA8875 lcd(p5, p6, p7, p12, NC, "tft"); // MOSI, MISO, SCK, /ChipSelect, /reset, name |
WiredHome | 0:9ecf49d75058 | 54 | Serial pc(USBTX, USBRX); |
WiredHome | 0:9ecf49d75058 | 55 | extern "C" void mbed_reset(); |
WiredHome | 0:9ecf49d75058 | 56 | |
WiredHome | 0:9ecf49d75058 | 57 | |
WiredHome | 0:9ecf49d75058 | 58 | // Not all systems have the LocalFileSystem. Plug in the library and driver for yours. |
WiredHome | 0:9ecf49d75058 | 59 | LocalFileSystem local("local"); // BMP test |
WiredHome | 0:9ecf49d75058 | 60 | |
WiredHome | 0:9ecf49d75058 | 61 | typedef struct { |
WiredHome | 0:9ecf49d75058 | 62 | loc_t x; |
WiredHome | 0:9ecf49d75058 | 63 | loc_t y; |
WiredHome | 0:9ecf49d75058 | 64 | char * filename; |
WiredHome | 0:9ecf49d75058 | 65 | } TestImage_T; |
WiredHome | 0:9ecf49d75058 | 66 | |
WiredHome | 0:9ecf49d75058 | 67 | TestImage_T TestImage[] = { |
WiredHome | 0:9ecf49d75058 | 68 | { 0, 0, "/local/01601602.bmp"}, |
WiredHome | 0:9ecf49d75058 | 69 | { 0, 0, "/local/48027224.bmp"}, |
WiredHome | 0:9ecf49d75058 | 70 | { 0, 0, "/local/48027208.bmp"}, |
WiredHome | 0:9ecf49d75058 | 71 | { 0, 0, "/local/48027204.bmp"}, |
WiredHome | 0:9ecf49d75058 | 72 | { 0, 0, "/local/48027202.bmp"}, |
WiredHome | 12:93adb3470150 | 73 | { 0, 0, "/local/testimg.jpg"}, |
WiredHome | 0:9ecf49d75058 | 74 | { 0, 0, "/local/TestPat.bmp"} |
WiredHome | 0:9ecf49d75058 | 75 | }; |
WiredHome | 0:9ecf49d75058 | 76 | |
WiredHome | 0:9ecf49d75058 | 77 | // deefine your screen size and color depth. |
WiredHome | 0:9ecf49d75058 | 78 | #define SCREEN_W 480 |
WiredHome | 0:9ecf49d75058 | 79 | #define SCREEN_H 272 |
WiredHome | 0:9ecf49d75058 | 80 | #define SCREEN_BPP 16 |
WiredHome | 0:9ecf49d75058 | 81 | |
WiredHome | 1:84fb3e9adaaf | 82 | #ifdef JPEG_TEST |
WiredHome | 2:1e1dd697d12d | 83 | //#include "tjpgd.h" |
WiredHome | 2:1e1dd697d12d | 84 | //JDEC jdec; |
WiredHome | 2:1e1dd697d12d | 85 | //#define JPEG_WORK_SPACE_SIZE 3100 |
WiredHome | 2:1e1dd697d12d | 86 | //uint16_t work[JPEG_WORK_SPACE_SIZE/sizeof(uint16_t)]; |
WiredHome | 2:1e1dd697d12d | 87 | //FILE *fh; |
WiredHome | 1:84fb3e9adaaf | 88 | |
WiredHome | 1:84fb3e9adaaf | 89 | uint16_t jpeg_input_func(JDEC *jd, uint8_t *buff, uint16_t ndata) |
WiredHome | 1:84fb3e9adaaf | 90 | { |
WiredHome | 1:84fb3e9adaaf | 91 | //INFO("Read in %p count %d", buff, ndata); |
WiredHome | 1:84fb3e9adaaf | 92 | if (buff) { |
WiredHome | 2:1e1dd697d12d | 93 | size_t n = fread(buff, 1, ndata, (FILE *)jd->device); |
WiredHome | 1:84fb3e9adaaf | 94 | //INFO("fread returned %d", n); |
WiredHome | 1:84fb3e9adaaf | 95 | //HexDump("buf", buff, (ndata > 32) ? 32 : ndata); |
WiredHome | 1:84fb3e9adaaf | 96 | return n == (size_t)-1 ? 0 : n; |
WiredHome | 1:84fb3e9adaaf | 97 | } else { |
WiredHome | 2:1e1dd697d12d | 98 | off_t t = fseek((FILE *)jd->device, ndata, SEEK_CUR); |
WiredHome | 1:84fb3e9adaaf | 99 | //INFO("Seek returned %d", t); |
WiredHome | 1:84fb3e9adaaf | 100 | return t == (off_t)-1 ? 0 : ndata; |
WiredHome | 1:84fb3e9adaaf | 101 | } |
WiredHome | 1:84fb3e9adaaf | 102 | } |
WiredHome | 1:84fb3e9adaaf | 103 | |
WiredHome | 1:84fb3e9adaaf | 104 | uint16_t jpeg_output_func(JDEC *jd, void *bitmap, JRECT *rect) |
WiredHome | 1:84fb3e9adaaf | 105 | { |
WiredHome | 1:84fb3e9adaaf | 106 | #if JD_FORMAT == 1 |
WiredHome | 1:84fb3e9adaaf | 107 | uint16_t *src = (uint16_t *)bitmap; |
WiredHome | 1:84fb3e9adaaf | 108 | #else |
WiredHome | 1:84fb3e9adaaf | 109 | uint8_t *src = (uint8_t *)bitmap; |
WiredHome | 1:84fb3e9adaaf | 110 | #endif |
WiredHome | 1:84fb3e9adaaf | 111 | int x0 = rect->left; |
WiredHome | 1:84fb3e9adaaf | 112 | int x1 = rect->right; |
WiredHome | 1:84fb3e9adaaf | 113 | int y0 = rect->top; |
WiredHome | 1:84fb3e9adaaf | 114 | int y1 = rect->bottom; |
WiredHome | 1:84fb3e9adaaf | 115 | |
WiredHome | 1:84fb3e9adaaf | 116 | if (y0 >= lcd.height() || x0 >= lcd.width()) |
WiredHome | 1:84fb3e9adaaf | 117 | return 1; |
WiredHome | 1:84fb3e9adaaf | 118 | |
WiredHome | 1:84fb3e9adaaf | 119 | if (x1 > lcd.width()-1) x1 = lcd.width() - 1; |
WiredHome | 1:84fb3e9adaaf | 120 | if (y1 > lcd.height()-1) y1 = lcd.height() - 1; |
WiredHome | 1:84fb3e9adaaf | 121 | |
WiredHome | 1:84fb3e9adaaf | 122 | if (x0 == 0) |
WiredHome | 1:84fb3e9adaaf | 123 | printf("\r %d", y0); |
WiredHome | 1:84fb3e9adaaf | 124 | |
WiredHome | 1:84fb3e9adaaf | 125 | int w = x1 - x0 + 1; |
WiredHome | 1:84fb3e9adaaf | 126 | for (int y= y0; y <= y1; y++) { |
WiredHome | 1:84fb3e9adaaf | 127 | lcd.SetGraphicsCursor(x0, y); |
WiredHome | 1:84fb3e9adaaf | 128 | lcd._StartGraphicsStream(); |
WiredHome | 1:84fb3e9adaaf | 129 | #if JD_FORMAT == 1 |
WiredHome | 1:84fb3e9adaaf | 130 | uint16_t *p = src + w * (y - y0); |
WiredHome | 1:84fb3e9adaaf | 131 | #else |
WiredHome | 1:84fb3e9adaaf | 132 | uint8_t *p = src + 3 * (w * (y - y0)); |
WiredHome | 1:84fb3e9adaaf | 133 | #endif |
WiredHome | 1:84fb3e9adaaf | 134 | for (int x=x0; x <= x1; x++) { |
WiredHome | 1:84fb3e9adaaf | 135 | #if JD_FORMAT == 1 |
WiredHome | 1:84fb3e9adaaf | 136 | lcd._putp(*p++); |
WiredHome | 1:84fb3e9adaaf | 137 | #else |
WiredHome | 1:84fb3e9adaaf | 138 | lcd._putp(RGB(*p, *(p+1), *(p+2))); |
WiredHome | 1:84fb3e9adaaf | 139 | p += 3; |
WiredHome | 1:84fb3e9adaaf | 140 | #endif |
WiredHome | 1:84fb3e9adaaf | 141 | } |
WiredHome | 1:84fb3e9adaaf | 142 | lcd._EndGraphicsStream(); |
WiredHome | 1:84fb3e9adaaf | 143 | } |
WiredHome | 1:84fb3e9adaaf | 144 | return 1; |
WiredHome | 1:84fb3e9adaaf | 145 | } |
WiredHome | 1:84fb3e9adaaf | 146 | #endif |
WiredHome | 1:84fb3e9adaaf | 147 | |
WiredHome | 1:84fb3e9adaaf | 148 | |
WiredHome | 0:9ecf49d75058 | 149 | int main() |
WiredHome | 0:9ecf49d75058 | 150 | { |
WiredHome | 0:9ecf49d75058 | 151 | pc.baud(460800); // I like a snappy terminal, so crank it up! |
WiredHome | 0:9ecf49d75058 | 152 | pc.printf("\r\nRA8875 Bitmap Test - Build " __DATE__ " " __TIME__ "\r\n"); |
WiredHome | 0:9ecf49d75058 | 153 | |
WiredHome | 0:9ecf49d75058 | 154 | lcd.init(SCREEN_W, SCREEN_H, SCREEN_BPP); |
WiredHome | 2:1e1dd697d12d | 155 | lcd.Backlight(0.5f); |
WiredHome | 2:1e1dd697d12d | 156 | |
WiredHome | 0:9ecf49d75058 | 157 | int count = sizeof(TestImage)/sizeof(TestImage[0]); |
WiredHome | 0:9ecf49d75058 | 158 | for (int i=0; i<count; i++) { |
WiredHome | 0:9ecf49d75058 | 159 | lcd.cls(); |
WiredHome | 0:9ecf49d75058 | 160 | printf("RenderBitmapFile(%d, %d, %s) ", TestImage[i].x, TestImage[i].y, TestImage[i].filename); |
WiredHome | 2:1e1dd697d12d | 161 | RetCode_t r = lcd.RenderImageFile(TestImage[i].x, TestImage[i].y, TestImage[i].filename); |
WiredHome | 0:9ecf49d75058 | 162 | printf("returned %d\r\n", r); |
WiredHome | 0:9ecf49d75058 | 163 | wait(5); |
WiredHome | 0:9ecf49d75058 | 164 | } |
WiredHome | 0:9ecf49d75058 | 165 | } |