Cherry-picked from upstream PR #465 Resolved conflicts: merged crop parameter with existing progressCallback, kept local dimension calculation and edge luminance caching logic
This commit is contained in:
parent
6ffd19a7e8
commit
c90304f59b
@ -447,7 +447,7 @@ bool Epub::generateCoverBmp(bool cropped) const {
|
|||||||
|
|
||||||
if (coverImageHref.substr(coverImageHref.length() - 4) == ".jpg" ||
|
if (coverImageHref.substr(coverImageHref.length() - 4) == ".jpg" ||
|
||||||
coverImageHref.substr(coverImageHref.length() - 5) == ".jpeg") {
|
coverImageHref.substr(coverImageHref.length() - 5) == ".jpeg") {
|
||||||
Serial.printf("[%lu] [EBP] Generating BMP from JPG cover image\n", millis());
|
Serial.printf("[%lu] [EBP] Generating BMP from JPG cover image (%s mode)\n", millis(), cropped ? "cropped" : "fit");
|
||||||
const auto coverJpgTempPath = getCachePath() + "/.cover.jpg";
|
const auto coverJpgTempPath = getCachePath() + "/.cover.jpg";
|
||||||
|
|
||||||
FsFile coverJpg;
|
FsFile coverJpg;
|
||||||
|
|||||||
@ -200,7 +200,8 @@ unsigned char JpegToBmpConverter::jpegReadCallback(unsigned char* pBuf, const un
|
|||||||
|
|
||||||
// Internal implementation with configurable target size and bit depth
|
// Internal implementation with configurable target size and bit depth
|
||||||
bool JpegToBmpConverter::jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bmpOut, int targetWidth, int targetHeight,
|
bool JpegToBmpConverter::jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bmpOut, int targetWidth, int targetHeight,
|
||||||
bool oneBit, const std::function<void(int)>& progressCallback) {
|
bool oneBit, bool crop,
|
||||||
|
const std::function<void(int)>& progressCallback) {
|
||||||
Serial.printf("[%lu] [JPG] Converting JPEG to %s BMP (target: %dx%d)\n", millis(), oneBit ? "1-bit" : "2-bit",
|
Serial.printf("[%lu] [JPG] Converting JPEG to %s BMP (target: %dx%d)\n", millis(), oneBit ? "1-bit" : "2-bit",
|
||||||
targetWidth, targetHeight);
|
targetWidth, targetHeight);
|
||||||
|
|
||||||
@ -242,8 +243,12 @@ bool JpegToBmpConverter::jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bm
|
|||||||
const float scaleToFitWidth = static_cast<float>(targetWidth) / imageInfo.m_width;
|
const float scaleToFitWidth = static_cast<float>(targetWidth) / imageInfo.m_width;
|
||||||
const float scaleToFitHeight = static_cast<float>(targetHeight) / imageInfo.m_height;
|
const float scaleToFitHeight = static_cast<float>(targetHeight) / imageInfo.m_height;
|
||||||
// We scale to the smaller dimension, so we can potentially crop later.
|
// We scale to the smaller dimension, so we can potentially crop later.
|
||||||
// TODO: ideally, we already crop here.
|
float scale = 1.0;
|
||||||
const float scale = (scaleToFitWidth > scaleToFitHeight) ? scaleToFitWidth : scaleToFitHeight;
|
if (crop) { // if we will crop, scale to the smaller dimension
|
||||||
|
scale = (scaleToFitWidth > scaleToFitHeight) ? scaleToFitWidth : scaleToFitHeight;
|
||||||
|
} else { // else, scale to the larger dimension to fit
|
||||||
|
scale = (scaleToFitWidth < scaleToFitHeight) ? scaleToFitWidth : scaleToFitHeight;
|
||||||
|
}
|
||||||
|
|
||||||
outWidth = static_cast<int>(imageInfo.m_width * scale);
|
outWidth = static_cast<int>(imageInfo.m_width * scale);
|
||||||
outHeight = static_cast<int>(imageInfo.m_height * scale);
|
outHeight = static_cast<int>(imageInfo.m_height * scale);
|
||||||
@ -556,22 +561,22 @@ bool JpegToBmpConverter::jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bm
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Core function: Convert JPEG file to 2-bit BMP (uses default target size)
|
// Core function: Convert JPEG file to 2-bit BMP (uses default target size)
|
||||||
bool JpegToBmpConverter::jpegFileToBmpStream(FsFile& jpegFile, Print& bmpOut) {
|
bool JpegToBmpConverter::jpegFileToBmpStream(FsFile& jpegFile, Print& bmpOut, bool crop) {
|
||||||
return jpegFileToBmpStreamInternal(jpegFile, bmpOut, TARGET_MAX_WIDTH, TARGET_MAX_HEIGHT, false, nullptr);
|
return jpegFileToBmpStreamInternal(jpegFile, bmpOut, TARGET_MAX_WIDTH, TARGET_MAX_HEIGHT, false, crop, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert with custom target size (for thumbnails, 2-bit)
|
// Convert with custom target size (for thumbnails, 2-bit)
|
||||||
bool JpegToBmpConverter::jpegFileToBmpStreamWithSize(FsFile& jpegFile, Print& bmpOut, int targetMaxWidth,
|
bool JpegToBmpConverter::jpegFileToBmpStreamWithSize(FsFile& jpegFile, Print& bmpOut, int targetMaxWidth,
|
||||||
int targetMaxHeight,
|
int targetMaxHeight,
|
||||||
const std::function<void(int)>& progressCallback) {
|
const std::function<void(int)>& progressCallback) {
|
||||||
return jpegFileToBmpStreamInternal(jpegFile, bmpOut, targetMaxWidth, targetMaxHeight, false, progressCallback);
|
return jpegFileToBmpStreamInternal(jpegFile, bmpOut, targetMaxWidth, targetMaxHeight, false, true, progressCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to 1-bit BMP (black and white only, no grays) for fast home screen rendering
|
// Convert to 1-bit BMP (black and white only, no grays) for fast home screen rendering
|
||||||
bool JpegToBmpConverter::jpegFileTo1BitBmpStreamWithSize(FsFile& jpegFile, Print& bmpOut, int targetMaxWidth,
|
bool JpegToBmpConverter::jpegFileTo1BitBmpStreamWithSize(FsFile& jpegFile, Print& bmpOut, int targetMaxWidth,
|
||||||
int targetMaxHeight,
|
int targetMaxHeight,
|
||||||
const std::function<void(int)>& progressCallback) {
|
const std::function<void(int)>& progressCallback) {
|
||||||
return jpegFileToBmpStreamInternal(jpegFile, bmpOut, targetMaxWidth, targetMaxHeight, true, progressCallback);
|
return jpegFileToBmpStreamInternal(jpegFile, bmpOut, targetMaxWidth, targetMaxHeight, true, true, progressCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get JPEG dimensions without full conversion
|
// Get JPEG dimensions without full conversion
|
||||||
|
|||||||
@ -10,10 +10,11 @@ class JpegToBmpConverter {
|
|||||||
static unsigned char jpegReadCallback(unsigned char* pBuf, unsigned char buf_size,
|
static unsigned char jpegReadCallback(unsigned char* pBuf, unsigned char buf_size,
|
||||||
unsigned char* pBytes_actually_read, void* pCallback_data);
|
unsigned char* pBytes_actually_read, void* pCallback_data);
|
||||||
static bool jpegFileToBmpStreamInternal(class FsFile& jpegFile, Print& bmpOut, int targetWidth, int targetHeight,
|
static bool jpegFileToBmpStreamInternal(class FsFile& jpegFile, Print& bmpOut, int targetWidth, int targetHeight,
|
||||||
bool oneBit, const std::function<void(int)>& progressCallback = nullptr);
|
bool oneBit, bool crop,
|
||||||
|
const std::function<void(int)>& progressCallback = nullptr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static bool jpegFileToBmpStream(FsFile& jpegFile, Print& bmpOut);
|
static bool jpegFileToBmpStream(FsFile& jpegFile, Print& bmpOut, bool crop = true);
|
||||||
// Convert with custom target size (for thumbnails)
|
// Convert with custom target size (for thumbnails)
|
||||||
static bool jpegFileToBmpStreamWithSize(FsFile& jpegFile, Print& bmpOut, int targetMaxWidth, int targetMaxHeight,
|
static bool jpegFileToBmpStreamWithSize(FsFile& jpegFile, Print& bmpOut, int targetMaxWidth, int targetMaxHeight,
|
||||||
const std::function<void(int)>& progressCallback = nullptr);
|
const std::function<void(int)>& progressCallback = nullptr);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user