Skip to content

Commit

Permalink
Merge pull request #38 from tobozo/png-encoding
Browse files Browse the repository at this point in the history
Added PNG encoding to ScreenShotService
  • Loading branch information
tobozo authored Oct 10, 2020
2 parents 971509d + 0578bdb commit b267b25
Show file tree
Hide file tree
Showing 12 changed files with 185 additions and 17 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ before_install:
# Install the library from the repository
- install_library
- install_library "LovyanGFX"
#- install_library "https://github.com/lovyan03/LovyanGFX/archive/develop.zip"
- install_package "esp32:esp32" "https://dl.espressif.com/dl/package_esp32_index.json"
# - install_package "m5stack:esp32" "https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json" # m5stack:esp32:m5stack-core2
# install ESP32-Chimera-Core custom boards + pins variants
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"name": "LovyanGFX"
}
],
"version": "1.1.1",
"version": "1.1.2",
"framework": "arduino",
"platforms": "espressif32"
}
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=ESP32-Chimera-Core
version=1.1.1
version=1.1.2
author=Lovyan03 & Tobozo
maintainer[email protected]
sentence=Alternate library M5Stack/M5Core2/Odroid-Go/D-Duino and possiblly other ESP32/TFT/SD bundles
Expand Down
2 changes: 1 addition & 1 deletion src/ESP32-Chimera-Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
#include "Config.h"

#include "helpers/TouchButton.h"
#include "helpers/ScreenShot.h"
#include "helpers/ScreenShotService/ScreenShot.h"

#include "drivers/common/Button/Button.h"
#include "drivers/common/Speaker/Speaker.h"
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#ifndef __TINY_BMP_ENCODER_H
#define __TINY_BMP_ENCODER_H

#include "../M5Display.h"
#include "../../../M5Display.h"

class BMP_Encoder {

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
#ifndef __TINY_JPEG_ENCODER__
#define __TINY_JPEG_ENCODER__

#include "../M5Display.h"
#include "../../../M5Display.h"
// C std lib
#include <assert.h>
#include <inttypes.h>
Expand Down
88 changes: 88 additions & 0 deletions src/helpers/ScreenShotService/PNG/FatPNGEncoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*\
*
* FatPNGEncoder
*
* Copyright 2020 tobozo http://github.com/tobozo
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files ("TinyBMPEncoder"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
\*/

#include "FatPNGEncoder.h"
#include "lgfx/utility/miniz.h"


void PNG_Encoder::init( M5Display *tft, fs::FS &fileSystem ) {
_tft = tft;
_fileSystem = &fileSystem;
if( !psramInit() ) {
log_n("[INFO] No PSRAM found, PNG Encoding is disabled");
}
}

bool PNG_Encoder::encodeToFile( const char* filename, const int imageW, const int imageH ) {

if( !psramInit() ) {
log_n("[ERROR] No PSRAM found, aborting");
return false;
}

rgbBuffer = (RGBColor*)ps_malloc( (imageW*imageH*3)+1 );

if (!rgbBuffer) {
log_n( "[ERROR] Can't malloc() image pixels, aborting" );
return false;
}

_tft->readRectRGB(0, 0, imageW, imageH, rgbBuffer );

size_t png_data_size = 0;
uint32_t time_start = millis();
bool success = false;

void *PNGDataPtr = tdefl_write_image_to_png_file_in_memory_ex(rgbBuffer, imageW, imageH, 3, &png_data_size, 6, 0);

if (!PNGDataPtr) {
log_n("[ERROR] PNG Encoding failed, bad PSRAM ?\n");
} else {
fs::File outFile = _fileSystem->open(filename, "wb"); // <-----fs:: added for compatibility with SdFat ------
if( ! outFile ) {
log_n( "[ERROR] Can't write capture file %s, make sure the path exists!", filename );
free(PNGDataPtr);
free(rgbBuffer);
return false;
}
outFile.write((uint8_t *)PNGDataPtr, png_data_size);
outFile.close();
//log_n("[SUCCESS] Wrote %d bytes into %s. Total time %u ms", png_data_size, filename, millis()-time_start);
}

free(PNGDataPtr);
free(rgbBuffer);

if( png_data_size > 0 ) {
return _fileSystem->exists( filename );
} else {
return false;
}

}
50 changes: 50 additions & 0 deletions src/helpers/ScreenShotService/PNG/FatPNGEncoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*\
*
* FatPNGEncoder
*
* Copyright 2020 tobozo http://github.com/tobozo
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files ("TinyBMPEncoder"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
\*/
#ifndef __FAT_PNG_ENCODER_H
#define __FAT_PNG_ENCODER_H


#include "../../../M5Display.h"

class PNG_Encoder {

public:

void init( M5Display *tft, fs::FS &fileSystem );
bool encodeToFile( const char* filename, const int imageW, const int imageH );

private:

RGBColor *rgbBuffer = NULL;
M5Display *_tft;
fs::FS * _fileSystem;

};

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ void ScreenShotService::init( M5Display *tft, fs::FS &fileSystem ) {
_tft = tft;
_fileSystem = &fileSystem;
BMPEncoder.init( tft, fileSystem );
PNGEncoder.init( tft, fileSystem );
JPEGEncoder.init( fileSystem );
}

Expand Down Expand Up @@ -101,7 +102,7 @@ bool ScreenShotService::displayCanReadPixels() {

void ScreenShotService::snap( const char* name, bool displayAfter ) {
if( readPixelSuccess == false ) {
log_e( "This TFT is unsupported, or it hasn't been tested yet" );
log_n( "[ERROR] This TFT is unsupported, or it hasn't been tested yet" );
return;
}
if( jpegCapture ) { // enough ram allocated?
Expand All @@ -120,15 +121,15 @@ static void jpeg_encoder_callback(uint32_t y, uint32_t h, unsigned char* rgbBuff

void ScreenShotService::snapJPG( const char* name, bool displayAfter ) {
if( !jpegCapture ) return;

genFileName( name, "jpg" );

// _tft->readRectRGB( 0, 0, _tft->width(), _tft->height(), rgbBuffer );

uint32_t time_start = millis();
if ( !JPEGEncoder.encodeToFile( fileName, _tft->width(), _tft->height(), 3 /*3=RGB,4=RGBA*/, rgbBuffer, &jpeg_encoder_callback, _tft ) ) {
log_e( "[ERROR] Could not write JPG file to: %s", fileName );
log_n( "[ERROR] Could not write JPG file to: %s", fileName );
} else {
Serial.printf( "Screenshot saved as %s\n", fileName );
fs::File outFile = _fileSystem->open( fileName );
size_t fileSize = outFile.size();
outFile.close();
log_n( "[SUCCESS] Screenshot saved as %s (%d bytes). Total time %u ms", fileName, fileSize, millis()-time_start);
if( displayAfter ) {
snapAnimation();
_tft->drawJpgFile( *_fileSystem, fileName, 0, 0, _tft->width(), _tft->height(), 0, 0, JPEG_DIV_NONE );
Expand All @@ -140,10 +141,14 @@ void ScreenShotService::snapJPG( const char* name, bool displayAfter ) {

void ScreenShotService::snapBMP( const char* name, bool displayAfter ) {
genFileName( name, "bmp" );
uint32_t time_start = millis();
if( !BMPEncoder.encodeToFile( fileName, _tft->width(), _tft->height() ) ) {
log_e( "[ERROR] Could not write BMP file to: %s", fileName );
} else {
Serial.printf( "Screenshot saved as %s\n", fileName );
fs::File outFile = _fileSystem->open( fileName );
size_t fileSize = outFile.size();
outFile.close();
log_n( "[SUCCESS] Screenshot saved as %s (%d bytes). Total time %u ms", fileName, fileSize, millis()-time_start);
if( displayAfter ) {
snapAnimation();
_tft->drawBmpFile( *_fileSystem, fileName, 0, 0 );
Expand All @@ -153,6 +158,25 @@ void ScreenShotService::snapBMP( const char* name, bool displayAfter ) {
}


void ScreenShotService::snapPNG( const char* name, bool displayAfter ) {
genFileName( name, "png" );
uint32_t time_start = millis();
if( !PNGEncoder.encodeToFile( fileName, _tft->width(), _tft->height() ) ) {
log_e( "[ERROR] Could not write PNG file to: %s", fileName );
} else {
fs::File outFile = _fileSystem->open( fileName );
size_t fileSize = outFile.size();
outFile.close();
log_n( "[SUCCESS] Screenshot saved as %s (%d bytes). Total time %u ms", fileName, fileSize, millis()-time_start);
if( displayAfter ) {
snapAnimation();
_tft->drawPngFile( *_fileSystem, fileName, 0, 0 );
delay(5000);
}
}
}


void ScreenShotService::checkFolder( const char* path ) {
*folderName = {0};
if( path[0] =='/' ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@


//#pragma message ("Screenshots support enabled !!")
#include "../M5Display.h"
#include "TinyJPEGEncoder.h"
#include "TinyBMPEncoder.h"
#include "../../M5Display.h"
#include "./JPG/TinyJPEGEncoder.h"
#include "./BMP/TinyBMPEncoder.h"
#include "./PNG/FatPNGEncoder.h" // requires PSRAM

class ScreenShotService {

Expand All @@ -53,7 +54,7 @@ class ScreenShotService {
void snap( const char* name = "screenshot", bool displayAfter = false );
void snapJPG( const char* name = "screenshot", bool displayAfter = false );
void snapBMP( const char* name = "screenshot", bool displayAfter = false );

void snapPNG( const char* name = "screenshot", bool displayAfter = false );
bool readPixelSuccess = false; // result of tft pixel read test
bool jpegCapture = true; // default yes until tested, BMP capture will be used if not enough ram is available

Expand All @@ -74,6 +75,10 @@ class ScreenShotService {

JPEG_Encoder JPEGEncoder;
BMP_Encoder BMPEncoder;
//#ifdef BOARD_HAS_PSRAM
PNG_Encoder PNGEncoder;
//#endif


uint8_t* rgbBuffer = NULL; // used for jpeg only, bmp has his own

Expand Down

0 comments on commit b267b25

Please sign in to comment.