Faster bmp loading

This commit is contained in:
nitko12 2020-08-07 09:33:42 +02:00
parent d5826251bf
commit 670d38946f
4 changed files with 139 additions and 44 deletions

View File

@ -1012,9 +1012,11 @@ int Inkplate::drawMonochromeBitmapSd(SdFile *f, struct bitmapHeader bmpHeader, i
int i, j; int i, j;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
uint8_t *bufferPtr = pixelBuffer;
f->read(pixelBuffer, w * 4);
for (i = 0; i < w; i++) for (i = 0; i < w; i++)
{ {
uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read(); uint32_t pixelRow = *(bufferPtr++) << 24 | *(bufferPtr++) << 16 | *(bufferPtr++) << 8 | *(bufferPtr++);
if (invert) if (invert)
pixelRow = ~pixelRow; pixelRow = ~pixelRow;
for (int n = 0; n < 32; n++) for (int n = 0; n < 32; n++)
@ -1048,9 +1050,11 @@ int Inkplate::drawGrayscaleBitmap4Sd(SdFile *f, struct bitmapHeader bmpHeader, i
int i, j; int i, j;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
uint8_t *bufferPtr = pixelBuffer;
f->read(pixelBuffer, w * 4);
for (i = 0; i < w; i++) for (i = 0; i < w; i++)
{ {
uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read(); uint32_t pixelRow = *(bufferPtr++) << 24 | *(bufferPtr++) << 16 | *(bufferPtr++) << 8 | *(bufferPtr++);
if (invert) if (invert)
pixelRow = ~pixelRow; pixelRow = ~pixelRow;
for (int n = 0; n < 8; n++) for (int n = 0; n < 8; n++)
@ -1082,13 +1086,15 @@ int Inkplate::drawGrayscaleBitmap8Sd(SdFile *f, struct bitmapHeader bmpHeader, i
int i, j; int i, j;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
uint8_t *bufferPtr = pixelBuffer;
f->read(pixelBuffer, w);
for (i = 0; i < w; i++) for (i = 0; i < w; i++)
{ {
uint8_t px = 0; uint8_t px = 0;
if (invert) if (invert)
px = 255 - f->read(); px = 255 - *(bufferPtr++);
else else
px = f->read(); px = *(bufferPtr++);
drawPixel(i + x, h - 1 - j + y, px >> 5); drawPixel(i + x, h - 1 - j + y, px >> 5);
} }
if (padding) if (padding)
@ -1112,6 +1118,8 @@ int Inkplate::drawGrayscaleBitmap24Sd(SdFile *f, struct bitmapHeader bmpHeader,
int i, j; int i, j;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
uint8_t *bufferPtr = pixelBuffer;
f->read(pixelBuffer, w * 3);
for (i = 0; i < w; i++) for (i = 0; i < w; i++)
{ {
//This is the proper way of converting True Color (24 Bit RGB) bitmap file into grayscale, but it takes waaay too much time (full size picture takes about 17s to decode!) //This is the proper way of converting True Color (24 Bit RGB) bitmap file into grayscale, but it takes waaay too much time (full size picture takes about 17s to decode!)
@ -1119,12 +1127,12 @@ int Inkplate::drawGrayscaleBitmap24Sd(SdFile *f, struct bitmapHeader bmpHeader,
//px = pow(px, 1.5); //px = pow(px, 1.5);
//display.drawPixel(i + x, h - j + y, (uint8_t)(px*7)); //display.drawPixel(i + x, h - j + y, (uint8_t)(px*7));
//So then, we are convertng it to grayscale using good old average and gamma correction (from LUT). With this metod, it is still slow (full size image takes 4 seconds), but much beter than prev mentioned method.
uint8_t px = 0; uint8_t px = 0;
//So then, we are convertng it to grayscale using good old average and gamma correction (from LUT). With this metod, it is still slow (full size image takes 4 seconds), but much beter than prev mentioned method.
if (invert) if (invert)
px = ((255 - f->read()) * 2126 / 10000) + ((255 - f->read()) * 7152 / 10000) + ((255 - f->read()) * 722 / 10000); px = ((255 - *(bufferPtr++)) * 2126 / 10000) + ((255 - *(bufferPtr++)) * 7152 / 10000) + ((255 - *(bufferPtr++)) * 722 / 10000);
else else
px = (f->read() * 2126 / 10000) + (f->read() * 7152 / 10000) + (f->read() * 722 / 10000); px = (*(bufferPtr++) * 2126 / 10000) + (*(bufferPtr++) * 7152 / 10000) + (*(bufferPtr++) * 722 / 10000);
//drawPixel(i + x, h - j + y, gammaLUT[px]); //drawPixel(i + x, h - j + y, gammaLUT[px]);
drawPixel(i + x, h - 1 - j + y, px >> 5); drawPixel(i + x, h - 1 - j + y, px >> 5);
//drawPixel(i + x, h - j + y, px/32); //drawPixel(i + x, h - j + y, px/32);

View File

@ -223,6 +223,7 @@ public:
private: private:
uint8_t gammaLUT[256]; uint8_t gammaLUT[256];
uint8_t pixelBuffer[800 * 3 + 5];
int8_t _temperature; int8_t _temperature;
uint8_t _panelOn = 0; uint8_t _panelOn = 0;
uint8_t _rotation = 0; uint8_t _rotation = 0;

View File

@ -0,0 +1,83 @@
#include "Inkplate.h"
#include "SdFat.h"
Inkplate display(INKPLATE_3BIT);
SdFile file;
void setup() {
Serial.begin(115200);
display.begin();
display.clearDisplay();
display.display();
}
void loop() {
if (display.sdCardInit()) {
Serial.println("1");
display.println("SD Card OK! Reading image...");
display.partialUpdate();
if (!display.drawBitmapFromSD("1bit.bmp", 0, 0, 1)) {
display.println("Image open error");
display.display();
}
display.display();
}
delay(5000);
display.clearDisplay();
display.clean();
display.display();
if (display.sdCardInit()) {
Serial.println("2");
display.println("SD Card OK! Reading image...");
display.partialUpdate();
if (!display.drawBitmapFromSD("4bit.bmp", 0, 0)) {
display.println("Image open error");
display.display();
}
display.display();
}
delay(5000);
display.clearDisplay();
display.clean();
display.display();
if (display.sdCardInit()) {
Serial.println("3");
display.println("SD Card OK! Reading image...");
display.partialUpdate();
if (!display.drawBitmapFromSD("8bit.bmp", 0, 0)) {
display.println("Image open error");
display.display();
}
display.display();
}
delay(5000);
display.clearDisplay();
display.clean();
display.display();
if (display.sdCardInit()) {
Serial.println("4");
display.println("SD Card OK! Reading image...");
display.partialUpdate();
if (!display.drawBitmapFromSD("24bit.bmp", 0, 0)) {
display.println("Image open error");
display.display();
}
display.display();
}
delay(5000);
display.clearDisplay();
display.clean();
display.display();
}

View File

@ -27,42 +27,45 @@ Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and a
SdFile file; //Create SdFile object used for accessing files on SD card SdFile file; //Create SdFile object used for accessing files on SD card
void setup() { void setup() {
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE) Serial.begin(115200);
display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on display
//Init SD card. Display if SD card is init propery or not. display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
if (display.sdCardInit()) { display.clearDisplay(); //Clear frame buffer of display
display.println("SD Card OK! Reading image..."); display.display(); //Put clear image on display
display.partialUpdate();
//If card is properly init, try to load image and display it on e-paper at position X=0, Y=0 //Init SD card. Display if SD card is init propery or not.
//NOTE: Both drawBitmapFromSD methods allow for an optional fourth "invert" parameter. Setting this parameter to true if (display.sdCardInit()) {
//will flip all colors on the image, making black white and white black. This may be necessary when exporting bitmaps from display.println("SD Card OK! Reading image...");
//certain softwares. display.partialUpdate();
if(!display.drawBitmapFromSD("image1.bmp", 0, 0)) {
//If is something failed (wrong filename or wrong bitmap format), write error message on the screen. //If card is properly init, try to load image and display it on e-paper at position X=0, Y=0
//REMEMBER! You can only use Windows Bitmap file with color depth of 1, 4, 8 or 24 bits with no compression! //NOTE: Both drawBitmapFromSD methods allow for an optional fourth "invert" parameter. Setting this parameter to true
display.println("Image open error"); //will flip all colors on the image, making black white and white black. This may be necessary when exporting bitmaps from
display.display(); //certain softwares.
if (!display.drawBitmapFromSD("image1.bmp", 0, 0)) {
//If is something failed (wrong filename or wrong bitmap format), write error message on the screen.
//REMEMBER! You can only use Windows Bitmap file with color depth of 1, 4, 8 or 24 bits with no compression!
display.println("Image open error");
display.display();
}
display.display();
} }
display.display(); else {
} else { //If SD card init not success, display error on screen and stop the program (using infinite loop)
//If SD card init not success, display error on screen and stop the program (using infinite loop) display.println("SD Card error!");
display.println("SD Card error!"); display.partialUpdate();
display.partialUpdate(); while (true);
while(true); }
} delay(5000);
delay(5000);
//Now try to load image using SdFat library class (for more advanced users) and display image on epaper. //Now try to load image using SdFat library class (for more advanced users) and display image on epaper.
if(file.open("image2.bmp", O_RDONLY)) { if (file.open("image2.bmp", O_RDONLY)) {
display.drawBitmapFromSD(&file, 0, 0); display.drawBitmapFromSD(&file, 0, 0);
display.display(); display.display();
} }
} }
void loop() { void loop() {
//Nothing... //Nothing...
} }