Added PNG and, adding tests.
This commit is contained in:
parent
57a406f57a
commit
1fd65df81b
|
@ -1,17 +1,16 @@
|
|||
#include "Image.h"
|
||||
|
||||
#include "../libs/TJpeg/TJpg_Decoder.h"
|
||||
#include "defines.h"
|
||||
#include "pgmspace.h"
|
||||
|
||||
#define RED(a) ((((a)&0xf800) >> 11) << 3)
|
||||
#define GREEN(a) ((((a)&0x07e0) >> 5) << 2)
|
||||
#define BLUE(a) (((a)&0x001f) << 3)
|
||||
|
||||
Image *_imagePtrJpeg = nullptr;
|
||||
Image *_imagePtrPng = nullptr;
|
||||
|
||||
Image::Image(int16_t w, int16_t h) : Adafruit_GFX(w, h)
|
||||
{
|
||||
_imagePtrJpeg = this;
|
||||
_imagePtrPng = this;
|
||||
}
|
||||
|
||||
bool Image::drawImage(const String path, int x, int y, bool dither, bool invert)
|
||||
|
@ -28,7 +27,7 @@ bool Image::drawImage(const char *path, int x, int y, bool dither, bool invert)
|
|||
if (strstr(path, ".jpg") != NULL || strstr(path, ".jpeg") != NULL)
|
||||
return drawJpegFromWeb(path, x, y, dither, invert);
|
||||
if (strstr(path, ".png") != NULL)
|
||||
return drawJpegFromWeb(path, x, y, dither, invert);
|
||||
return drawPngFromWeb(path, x, y, dither, invert);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -37,7 +36,7 @@ bool Image::drawImage(const char *path, int x, int y, bool dither, bool invert)
|
|||
if (strstr(path, ".jpg") != NULL || strstr(path, ".jpeg") != NULL)
|
||||
return drawJpegFromSd(path, x, y, dither, invert);
|
||||
if (strstr(path, ".png") != NULL)
|
||||
return drawJpegFromSd(path, x, y, dither, invert);
|
||||
return drawPngFromSd(path, x, y, dither, invert);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
class Image : virtual public NetworkClient, virtual public Adafruit_GFX
|
||||
{
|
||||
public:
|
||||
public:
|
||||
Image(int16_t w, int16_t h);
|
||||
|
||||
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
|
||||
|
@ -33,27 +33,45 @@ public:
|
|||
|
||||
bool drawBitmapFromBuffer(uint8_t *buf, int x, int y, bool dither, bool invert);
|
||||
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawBitmapFromSd(const char *fileName, int x, int y, bool dither = 0, bool invert = 0);
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawBitmapFromSd(
|
||||
const char *fileName, int x, int y, bool dither = 0, bool invert = 0);
|
||||
bool drawBitmapFromSd(SdFile *p, int x, int y, bool dither = 0, bool invert = 0);
|
||||
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawBitmapFromWeb(const char *url, int x, int y, bool dither = 0, bool invert = 0);
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawBitmapFromWeb(const char *url,
|
||||
int x, int y,
|
||||
bool dither = 0,
|
||||
bool invert = 0);
|
||||
bool drawBitmapFromWeb(WiFiClient *s, int x, int y, int32_t len, bool dither = 0, bool invert = 0);
|
||||
|
||||
bool drawJpegFromBuffer(uint8_t *buf, int32_t len, int x, int y, bool dither, bool invert);
|
||||
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawJpegFromSd(const char *fileName, int x, int y, bool dither = 0, bool invert = 0);
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawJpegFromSd(
|
||||
const char *fileName, int x, int y, bool dither = 0, bool invert = 0);
|
||||
bool drawJpegFromSd(SdFile *p, int x, int y, bool dither = 0, bool invert = 0);
|
||||
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawJpegFromWeb(const char *url, int x, int y, bool dither = 0, bool invert = 0);
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawJpegFromWeb(const char *url,
|
||||
int x, int y,
|
||||
bool dither = 0,
|
||||
bool invert = 0);
|
||||
bool drawJpegFromWeb(WiFiClient *s, int x, int y, int32_t len, bool dither = 0, bool invert = 0);
|
||||
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawPngFromSd(const char *fileName, int x, int y, bool dither = 0, bool invert = 0);
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawPngFromSd(const char *fileName,
|
||||
int x, int y,
|
||||
bool dither = 0,
|
||||
bool invert = 0);
|
||||
bool drawPngFromSd(SdFile *p, int x, int y, bool dither = 0, bool invert = 0);
|
||||
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawPngFromWeb(const char *url, int x, int y, bool dither = 0, bool invert = 0);
|
||||
[[deprecated("Use drawImage, as this will soon become a private method.")]] bool drawPngFromWeb(const char *url,
|
||||
int x, int y,
|
||||
bool dither = 0,
|
||||
bool invert = 0);
|
||||
bool drawPngFromWeb(WiFiClient *s, int x, int y, int32_t len, bool dither = 0, bool invert = 0);
|
||||
|
||||
private:
|
||||
// Should be private, but needed in a png callback :(
|
||||
void ditherSwap(int w);
|
||||
uint8_t ditherGetPixelBmp(uint8_t px, int i, int w, bool paletted);
|
||||
|
||||
private:
|
||||
virtual void startWrite(void) = 0;
|
||||
virtual void writePixel(int16_t x, int16_t y, uint16_t color) = 0;
|
||||
virtual void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) = 0;
|
||||
|
@ -75,9 +93,7 @@ private:
|
|||
|
||||
bool legalBmp(bitmapHeader *bmpHeader);
|
||||
|
||||
uint8_t ditherGetPixelBmp(uint8_t px, int i, int w, bool paletted);
|
||||
uint8_t ditherGetPixelJpeg(uint8_t px, int i, int j, int x, int y, int w, int h);
|
||||
void ditherSwap(int w);
|
||||
void ditherSwapBlockJpeg(int x);
|
||||
|
||||
void readBmpHeader(uint8_t *buf, bitmapHeader *_h);
|
||||
|
|
|
@ -73,7 +73,6 @@ void Image::readBmpHeader(uint8_t *buf, bitmapHeader *_h)
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
bool Image::drawBitmapFromSd(const char *fileName, int x, int y, bool dither, bool invert)
|
||||
{
|
||||
SdFile dat;
|
||||
|
@ -167,7 +166,8 @@ void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool d
|
|||
writePixel(x + j, y, (invert ^ (palette[0] < palette[1])) ^ !!(pixelBuffer[j >> 3] & (1 << (7 - (j & 7)))));
|
||||
break;
|
||||
// as for 2 bit, literally cannot find an example online or in PS, so skipped
|
||||
case 4: {
|
||||
case 4:
|
||||
{
|
||||
uint8_t px = pixelBuffer[j >> 1] & (j & 1 ? 0x0F : 0xF0) >> (j & 1 ? 0 : 4);
|
||||
uint8_t val;
|
||||
|
||||
|
@ -183,7 +183,8 @@ void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool d
|
|||
writePixel(x + j, y, val);
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
case 8:
|
||||
{
|
||||
uint8_t px = pixelBuffer[j];
|
||||
uint8_t val;
|
||||
|
||||
|
@ -199,7 +200,8 @@ void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool d
|
|||
writePixel(x + j, y, val);
|
||||
break;
|
||||
}
|
||||
case 16: {
|
||||
case 16:
|
||||
{
|
||||
uint16_t px = ((uint16_t)pixelBuffer[(j << 1) | 1] << 8) | pixelBuffer[(j << 1)];
|
||||
|
||||
uint8_t r = (px & 0x7C00) >> 7;
|
||||
|
@ -220,7 +222,8 @@ void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool d
|
|||
writePixel(x + j, y, val);
|
||||
break;
|
||||
}
|
||||
case 24: {
|
||||
case 24:
|
||||
{
|
||||
uint8_t r = pixelBuffer[j * 3];
|
||||
uint8_t g = pixelBuffer[j * 3 + 1];
|
||||
uint8_t b = pixelBuffer[j * 3 + 2];
|
||||
|
|
|
@ -1,23 +1,138 @@
|
|||
#include "Image.h"
|
||||
|
||||
#include "../libs/pngle/pngle.h"
|
||||
#include "defines.h"
|
||||
|
||||
extern Image *_imagePtrPng;
|
||||
|
||||
static bool _pngInvert = 0;
|
||||
static bool _pngDither = 0;
|
||||
static int16_t lastY = -1;
|
||||
|
||||
void pngle_on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4])
|
||||
{
|
||||
if (rgba[3])
|
||||
for (int j = 0; j < h; ++j)
|
||||
for (int i = 0; i < w; ++i)
|
||||
{
|
||||
uint8_t px = RGB3BIT(rgba[0], rgba[1], rgba[2]);
|
||||
if (_pngDither)
|
||||
px = _imagePtrPng->ditherGetPixelBmp(RGB8BIT(rgba[0], rgba[1], rgba[2]), x + i,
|
||||
_imagePtrPng->width(), 0);
|
||||
if (_pngInvert)
|
||||
px = 7 - px;
|
||||
if (_imagePtrPng->getDisplayMode() == INKPLATE_1BIT)
|
||||
px = (~px >> 2) & 1;
|
||||
_imagePtrPng->drawPixel(x + i, y + j, px);
|
||||
}
|
||||
if (lastY != y)
|
||||
{
|
||||
lastY = y;
|
||||
_imagePtrPng->ditherSwap(_imagePtrPng->width());
|
||||
}
|
||||
}
|
||||
|
||||
bool Image::drawPngFromSd(const char *fileName, int x, int y, bool dither, bool invert)
|
||||
{
|
||||
SdFile dat;
|
||||
if (dat.open(fileName, O_RDONLY))
|
||||
{
|
||||
return drawPngFromSd(&dat, x, y, dither, invert);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Image::drawPngFromSd(SdFile *p, int x, int y, bool dither, bool invert)
|
||||
{
|
||||
return 0;
|
||||
_pngDither = dither;
|
||||
_pngInvert = invert;
|
||||
lastY = y;
|
||||
|
||||
bool ret = 1;
|
||||
uint32_t remain = 0;
|
||||
|
||||
if (dither)
|
||||
memset(ditherBuffer, 0, sizeof ditherBuffer);
|
||||
|
||||
pngle_t *pngle = pngle_new();
|
||||
pngle_set_draw_callback(pngle, pngle_on_draw);
|
||||
uint32_t total = p->fileSize();
|
||||
uint8_t buff[2048];
|
||||
uint32_t pnt = 0;
|
||||
|
||||
while (pnt < total)
|
||||
{
|
||||
uint32_t toread = p->available();
|
||||
if (toread > 0)
|
||||
{
|
||||
int len = p->read(buff, min((uint32_t)2048, toread));
|
||||
int fed = pngle_feed(pngle, buff, len);
|
||||
if (fed < 0)
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
remain = remain + len - fed;
|
||||
pnt += len;
|
||||
}
|
||||
}
|
||||
|
||||
p->close();
|
||||
pngle_destroy(pngle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Image::drawPngFromWeb(const char *url, int x, int y, bool dither, bool invert)
|
||||
{
|
||||
_pngDither = dither;
|
||||
_pngInvert = invert;
|
||||
lastY = y;
|
||||
|
||||
bool ret = 1;
|
||||
|
||||
if (dither)
|
||||
memset(ditherBuffer, 0, sizeof ditherBuffer);
|
||||
|
||||
pngle_t *pngle = pngle_new();
|
||||
pngle_set_draw_callback(pngle, pngle_on_draw);
|
||||
|
||||
int32_t defaultLen = 800 * 600 * 4 + 100;
|
||||
uint8_t *buff = downloadFile(url, &defaultLen);
|
||||
|
||||
if (!buff)
|
||||
return 0;
|
||||
|
||||
if (pngle_feed(pngle, buff, defaultLen) < 0)
|
||||
ret = 0;
|
||||
|
||||
pngle_destroy(pngle);
|
||||
free(buff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Image::drawPngFromWeb(WiFiClient *s, int x, int y, int32_t len, bool dither, bool invert)
|
||||
{
|
||||
_pngDither = dither;
|
||||
_pngInvert = invert;
|
||||
lastY = y;
|
||||
|
||||
bool ret = 1;
|
||||
|
||||
if (dither)
|
||||
memset(ditherBuffer, 0, sizeof ditherBuffer);
|
||||
|
||||
pngle_t *pngle = pngle_new();
|
||||
pngle_set_draw_callback(pngle, pngle_on_draw);
|
||||
|
||||
uint8_t *buff = downloadFile(s, len);
|
||||
|
||||
if (!buff)
|
||||
return 0;
|
||||
|
||||
if (pngle_feed(pngle, buff, len) < 0)
|
||||
ret = 0;
|
||||
pngle_destroy(pngle);
|
||||
|
||||
free(buff);
|
||||
return ret;
|
||||
}
|
|
@ -22,4 +22,8 @@
|
|||
#define READ16(c) (uint16_t)(*(c) | (*((c) + 1) << 8))
|
||||
#define ROWSIZE(w, c) (((int16_t)c * w + 31) >> 5) << 2
|
||||
|
||||
#define RED(a) ((((a)&0xf800) >> 11) << 3)
|
||||
#define GREEN(a) ((((a)&0x07e0) >> 5) << 2)
|
||||
#define BLUE(a) (((a)&0x001f) << 3)
|
||||
|
||||
#endif
|
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
|
@ -8,9 +8,9 @@ Inkplate display(INKPLATE_1BIT);
|
|||
|
||||
#define DELAYMS 1000
|
||||
|
||||
const char *images[] = {"1bit.bmp", "4bit.bmp", "8bit.bmp", "16bit.bmp",
|
||||
const char *imagesBmp[] = {"1bit.bmp", "4bit.bmp", "8bit.bmp", "16bit.bmp",
|
||||
"24bit.bmp", "32bit.bmp", "Lenna.jpg", "Lenna.jpg"};
|
||||
const char *imageUrls[] = {
|
||||
const char *imagesBmpUrls[] = {
|
||||
"https://raw.githubusercontent.com/nitko12/Inkplate-revision/master/test/bitmaps/1bit.bmp",
|
||||
"https://raw.githubusercontent.com/nitko12/Inkplate-revision/master/test/bitmaps/4bit.bmp",
|
||||
"https://raw.githubusercontent.com/nitko12/Inkplate-revision/master/test/bitmaps/8bit.bmp",
|
||||
|
@ -86,14 +86,16 @@ void loop()
|
|||
bool dither = i & 1;
|
||||
bool invert = i >> 1;
|
||||
|
||||
for (int j = 0; j < 6; ++j)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
display.selectDisplayMode(depth[j]);
|
||||
bool dither = i & 1;
|
||||
bool invert = i >> 1;
|
||||
|
||||
display.selectDisplayMode(INKPLATE_1BIT);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(1);
|
||||
display.setCursor(100, 100);
|
||||
display.print("Displaying ");
|
||||
display.print(images[j]);
|
||||
display.print("Displaying Lenna.jpg 1bit");
|
||||
if (!dither)
|
||||
display.print(" non");
|
||||
display.print(" dithered and");
|
||||
|
@ -105,11 +107,91 @@ void loop()
|
|||
display.clearDisplay();
|
||||
delay(5000);
|
||||
|
||||
display.drawImage(images[j], 0, 0, dither, invert);
|
||||
display.drawImage("Lenna.jpg", 0, 0, dither, invert);
|
||||
display.display();
|
||||
display.clearDisplay();
|
||||
delay(5000);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
bool dither = i & 1;
|
||||
bool invert = i >> 1;
|
||||
|
||||
display.selectDisplayMode(INKPLATE_3BIT);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(1);
|
||||
display.setCursor(100, 100);
|
||||
display.print("Displaying Lenna.jpg 3bit");
|
||||
if (!dither)
|
||||
display.print(" non");
|
||||
display.print(" dithered and");
|
||||
if (!invert)
|
||||
display.print(" non");
|
||||
display.print(" inverted.");
|
||||
|
||||
display.display();
|
||||
display.clearDisplay();
|
||||
delay(5000);
|
||||
|
||||
display.drawImage("Lenna.jpg", 0, 0, dither, invert);
|
||||
display.display();
|
||||
display.clearDisplay();
|
||||
delay(5000);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
bool dither = i & 1;
|
||||
bool invert = i >> 1;
|
||||
|
||||
display.selectDisplayMode(INKPLATE_1BIT);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(1);
|
||||
display.setCursor(100, 100);
|
||||
display.print("Displaying png.png 1bit");
|
||||
if (!dither)
|
||||
display.print(" non");
|
||||
display.print(" dithered and");
|
||||
if (!invert)
|
||||
display.print(" non");
|
||||
display.print(" inverted.");
|
||||
|
||||
display.display();
|
||||
display.clearDisplay();
|
||||
delay(5000);
|
||||
|
||||
display.drawImage("png.jpg", 0, 0, dither, invert);
|
||||
display.display();
|
||||
display.clearDisplay();
|
||||
delay(5000);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
bool dither = i & 1;
|
||||
bool invert = i >> 1;
|
||||
|
||||
display.selectDisplayMode(INKPLATE_3BIT);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(1);
|
||||
display.setCursor(100, 100);
|
||||
display.print("Displaying png.png 3bit");
|
||||
if (!dither)
|
||||
display.print(" non");
|
||||
display.print(" dithered and");
|
||||
if (!invert)
|
||||
display.print(" non");
|
||||
display.print(" inverted.");
|
||||
|
||||
display.display();
|
||||
display.clearDisplay();
|
||||
delay(5000);
|
||||
|
||||
display.drawImage("png.jpg", 0, 0, dither, invert);
|
||||
display.display();
|
||||
display.clearDisplay();
|
||||
delay(5000);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
|
@ -145,4 +227,4 @@ void loop()
|
|||
}
|
||||
|
||||
delay(5000);
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 814 KiB |
|
@ -3,7 +3,7 @@
|
|||
|
||||
const int n = 500;
|
||||
|
||||
Inkplate display(INKPLATE_1BIT);
|
||||
Inkplate display(INKPLATE_3BIT);
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
@ -13,7 +13,6 @@ void setup()
|
|||
|
||||
display.joinAP("e-radionica.com", "croduino");
|
||||
|
||||
Serial.println("aaaa");
|
||||
delay(500);
|
||||
}
|
||||
|
||||
|
@ -21,34 +20,9 @@ void loop()
|
|||
{
|
||||
display.clearDisplay();
|
||||
|
||||
// Code block for generating random points and sorting them in a counter
|
||||
// clockwise direction.
|
||||
int xt[n];
|
||||
int yt[n];
|
||||
display.sdCardInit();
|
||||
display.drawPngFromSd("png.png", 0, 0, 1, 0);
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
xt[i] = random(100, 700);
|
||||
yt[i] = random(100, 500);
|
||||
}
|
||||
|
||||
int k;
|
||||
for (int i = 0; i < n - 1; ++i)
|
||||
|
||||
for (int j = i + 1; j < n; ++j)
|
||||
if (atan2(yt[j] - 300, xt[j] - 400) < atan2(yt[i] - 300, xt[i] - 400))
|
||||
{
|
||||
k = xt[i], xt[i] = xt[j], xt[j] = k;
|
||||
k = yt[i], yt[i] = yt[j], yt[j] = k;
|
||||
}
|
||||
|
||||
display.clearDisplay();
|
||||
display.drawPolygon(xt, yt, n, 1);
|
||||
display.display();
|
||||
delay(5000);
|
||||
|
||||
display.clearDisplay();
|
||||
display.fillPolygon(xt, yt, n, 1);
|
||||
display.display();
|
||||
delay(5000);
|
||||
}
|
Loading…
Reference in New Issue