add dithering and central image handling #17

pull/1/head
Thomas Ballmann 4 years ago
parent 332f3a7d6c
commit 44d1042946

@ -0,0 +1,13 @@
#ifndef IMAGE_H
#define IMAGE_H
#include <Arduino.h>
#include "imageWBMP.h"
#include "imagePNG.h"
void ImageNew(int x, int y, int w, int h, bool dithering);
void ImageWriteBuffer(uint8_t buff[], size_t c);
void ImageFlushBuffer();
#endif

@ -0,0 +1,91 @@
#include "image.h"
typedef struct
{
size_t format;
int x;
int y;
int w;
int h;
bool dithering;
} ImageProcess;
ImageProcess Image;
void ImageNew(int x, int y, int w, int h, bool dithering)
{
Image.x = x;
Image.y = y;
Image.w = w;
Image.h = h;
Image.dithering = dithering;
}
void ImageWriteBuffer(uint8_t buff[], size_t c)
{
// initial detect format
if (Image.format == 0)
{
if (memcmp(buff, ImageHeaderWBMP, sizeof(ImageHeaderWBMP) - 1) == 0)
{
Serial.println(" image format: WBMP");
Image.format = 2;
wbmpOpenFramebuffer();
}
else if (memcmp(buff, ImageHeaderPNG, sizeof(ImageHeaderPNG) - 1) == 0)
{
Serial.println(" image format: PNG");
Image.format = 3;
pngOpenFramebuffer();
}
else
{
Image.format = 1;
Serial.println(" unkown image format. first header are:");
Serial.println(buff[0]);
Serial.println(buff[1]);
Serial.println(buff[2]);
Serial.println(buff[3]);
Serial.println(buff[4]);
Serial.println(buff[5]);
}
}
// write display frame
switch (Image.format)
{
// WBMP
case 2:
wbmpWriteFramebuffer(0, buff, c);
break;
// PNG
case 3:
pngWriteFramebuffer(0, buff, c);
break;
}
}
void ImageFlushBuffer()
{
// update display
switch (Image.format)
{
// WBMP
case 2:
wbmpFlushFramebuffer();
break;
// PNG
case 3:
pngFlushFramebuffer();
break;
}
// clear settings
Image.format = 0;
Image.x = 0;
Image.y = 0;
Image.w = 0;
Image.h = 0;
Image.dithering = false;
}

@ -1,11 +1,17 @@
#include <Arduino.h>
#include "imagePNG.h"
#include "pngle.h"
//#include "SPIFFS.h"
#include "display.h"
pngle_t *pngle;
// TODO use dynamic display width
static constexpr int MAX_WIDTH = 640;
static int16_t curRowDelta[MAX_WIDTH + 1];
static int16_t nextRowDelta[MAX_WIDTH + 1];
bool dithering = true;
void on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4]);
void setupImagePNG()
@ -19,16 +25,28 @@ void pngOpenFramebuffer()
{
displayOpen();
if (pngle)
{
pngle_destroy(pngle);
}
pngle = pngle_new();
pngle_set_draw_callback(pngle, on_draw);
}
void pngWriteFramebuffer(int offset, uint8_t bitmap[], int c)
{
int fed = pngle_feed(pngle, bitmap, c);
if (fed < 0)
if (pngle)
{
Serial.println(pngle_error(pngle));
int fed = pngle_feed(pngle, bitmap, c);
if (fed < 0)
{
Serial.println(pngle_error(pngle));
}
}
else
{
Serial.println("forgot pngle_new() ?");
}
}
@ -38,63 +56,52 @@ void pngFlushFramebuffer()
displayFlush();
}
/*
void setupImagePNG__demo()
void on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4])
{
SPIFFS.begin();
displayOpen();
uint8_t r = rgba[0]; // 0 - 255
uint8_t g = rgba[1]; // 0 - 255
uint8_t b = rgba[2]; // 0 - 255
pngle_t *pngle = pngle_new();
pngle_set_draw_callback(pngle, on_draw);
int16_t gray = round(r * 0.3 + g * 0.59 + b * 0.11);
int16_t blackOrWhite;
File file = SPIFFS.open("/blackPNG.png", "r");
if (!file)
// Add errors to color if there are
if (dithering)
{
Serial.println(" file not found");
gray += curRowDelta[x];
}
// get filesize
long size = file.size();
// read contents of the file into the vector
char *buffer = (char *)malloc((unsigned long)size);
if (!buffer)
if (gray <= 127)
{
file.close();
Serial.println(" allow failedd");
blackOrWhite = 0;
}
else
{
blackOrWhite = 255;
}
file.readBytes(buffer, (size_t)size);
file.close();
Serial.println(" read png");
int ret = pngle_feed(pngle, buffer, size);
//Serial.println(" return: " + ret);
//Serial.println(" width: " + pngle_get_width(pngle));
//Serial.println(" height: " + pngle_get_height(pngle));
Serial.println(" read png done");
pngle_destroy(pngle);
if (dithering)
{
int16_t oldPixel = gray;
int16_t newPixel = blackOrWhite;
displayFlush();
}
*/
int err = oldPixel - newPixel;
void on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4])
{
uint8_t r = rgba[0]; // 0 - 255
//uint8_t g = rgba[1]; // 0 - 255
//uint8_t b = rgba[2]; // 0 - 255
uint8_t a = rgba[3]; // 0: fully transparent, 255: fully opaque
if (a)
{
// 640 x 384
if (true) // x == 0
if (x > 0)
{
//printf("put pixel at (%d, %d) with color #%02x%02x%02x\n", x, y, r, g, b);
nextRowDelta[x - 1] += err * 3 / 16;
}
nextRowDelta[x] += err * 5 / 16;
nextRowDelta[x + 1] += err * 1 / 16;
curRowDelta[x + 1] += err * 7 / 16;
displayWritePixel(x, y, r);
if (x == 0 && y > 0)
{
// new line
memcpy(curRowDelta, nextRowDelta, sizeof(&curRowDelta));
memset(nextRowDelta, 0, sizeof(&nextRowDelta));
}
}
displayWritePixel(x, y, blackOrWhite);
}
Loading…
Cancel
Save