mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-04 14:47:37 +03:00
Merge fcec6a0b97 into d403044f76
This commit is contained in:
commit
e290accd3e
@ -468,10 +468,47 @@ bool Epub::generateThumbBmp() const {
|
||||
coverJpg.close();
|
||||
return false;
|
||||
}
|
||||
// Use smaller target size for Continue Reading card (half of screen: 240x400)
|
||||
// Generate 1-bit BMP for fast home screen rendering (no gray passes needed)
|
||||
constexpr int THUMB_TARGET_WIDTH = 240;
|
||||
constexpr int THUMB_TARGET_HEIGHT = 400;
|
||||
|
||||
// Generate 1-bit BMP maintaining aspect ratio with fixed height of 400px
|
||||
// This ensures the card width adapts to the actual cover image aspect ratio
|
||||
const int THUMB_TARGET_HEIGHT = 400;
|
||||
|
||||
// Read a small portion of the JPG file to determine its dimensions
|
||||
uint8_t headerBuffer[200];
|
||||
size_t bytesRead = coverJpg.read(headerBuffer, sizeof(headerBuffer));
|
||||
coverJpg.seek(0); // Reset file position
|
||||
|
||||
int imgWidth = 240, imgHeight = 400; // Default fallback
|
||||
|
||||
// Simple header parsing to get image dimensions (works for most JPGs)
|
||||
if (bytesRead > 0) {
|
||||
// Look for SOF (Start of Frame) markers
|
||||
for (size_t i = 0; i < bytesRead - 10; i++) {
|
||||
if (headerBuffer[i] == 0xFF && headerBuffer[i + 1] == 0xC0) {
|
||||
// Found SOF0 marker
|
||||
if (i + 7 < bytesRead) {
|
||||
imgHeight = (headerBuffer[i + 5] << 8) | headerBuffer[i + 6];
|
||||
imgWidth = (headerBuffer[i + 7] << 8) | headerBuffer[i + 8];
|
||||
break;
|
||||
}
|
||||
} else if (headerBuffer[i] == 0xFF && headerBuffer[i + 1] == 0xC2) {
|
||||
// Found SOF2 marker
|
||||
if (i + 7 < bytesRead) {
|
||||
imgHeight = (headerBuffer[i + 5] << 8) | headerBuffer[i + 6];
|
||||
imgWidth = (headerBuffer[i + 7] << 8) | headerBuffer[i + 8];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate target width maintaining aspect ratio
|
||||
const float aspectRatio = static_cast<float>(imgWidth) / static_cast<float>(imgHeight);
|
||||
const int THUMB_TARGET_WIDTH = static_cast<int>(THUMB_TARGET_HEIGHT * aspectRatio);
|
||||
|
||||
Serial.printf("[%lu] [EBP] Original JPG: %dx%d, Target: %dx%d\n", millis(), imgWidth, imgHeight, THUMB_TARGET_WIDTH,
|
||||
THUMB_TARGET_HEIGHT);
|
||||
|
||||
const bool success = JpegToBmpConverter::jpegFileTo1BitBmpStreamWithSize(coverJpg, thumbBmp, THUMB_TARGET_WIDTH,
|
||||
THUMB_TARGET_HEIGHT);
|
||||
coverJpg.close();
|
||||
|
||||
@ -567,5 +567,5 @@ bool JpegToBmpConverter::jpegFileToBmpStreamWithSize(FsFile& jpegFile, Print& bm
|
||||
// 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,
|
||||
int targetMaxHeight) {
|
||||
return jpegFileToBmpStreamInternal(jpegFile, bmpOut, targetMaxWidth, targetMaxHeight, true);
|
||||
return jpegFileToBmpStreamInternal(jpegFile, bmpOut, targetMaxWidth, targetMaxHeight, true, false);
|
||||
}
|
||||
|
||||
@ -224,9 +224,50 @@ void HomeActivity::render() {
|
||||
constexpr int bottomMargin = 60;
|
||||
|
||||
// --- Top "book" card for the current title (selectorIndex == 0) ---
|
||||
const int bookWidth = pageWidth / 2;
|
||||
const int bookHeight = pageHeight / 2;
|
||||
const int bookX = (pageWidth - bookWidth) / 2;
|
||||
// When there's no cover image, use fixed size (half screen)
|
||||
// When there's cover image, adapt width to image aspect ratio, keep height fixed at 400px
|
||||
const int baseHeight = 400; // Fixed height for both scenarios
|
||||
|
||||
int bookWidth, bookX;
|
||||
if (hasCoverImage) {
|
||||
// When there's cover, calculate width based on image aspect ratio
|
||||
// Use default width ratio as fallback if we can't get image dimensions
|
||||
const float defaultWidthRatio = 0.5f; // Same as half screen
|
||||
bookWidth = static_cast<int>(pageWidth * defaultWidthRatio);
|
||||
|
||||
// If we have cover bitmap path, try to get actual image dimensions
|
||||
if (!coverBmpPath.empty()) {
|
||||
FsFile file;
|
||||
if (SdMan.openFileForRead("HOME", coverBmpPath, file)) {
|
||||
Bitmap bitmap(file);
|
||||
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
|
||||
const int imgWidth = bitmap.getWidth();
|
||||
const int imgHeight = bitmap.getHeight();
|
||||
|
||||
// Calculate width based on aspect ratio, maintaining 400px height
|
||||
if (imgHeight > 0) {
|
||||
const float aspectRatio = static_cast<float>(imgWidth) / static_cast<float>(imgHeight);
|
||||
bookWidth = static_cast<int>(baseHeight * aspectRatio);
|
||||
|
||||
// Ensure width doesn't exceed reasonable limits (max 90% of screen width)
|
||||
const int maxWidth = static_cast<int>(pageWidth * 0.9f);
|
||||
if (bookWidth > maxWidth) {
|
||||
bookWidth = maxWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
bookX = (pageWidth - bookWidth) / 2;
|
||||
} else {
|
||||
// No cover: use half screen size
|
||||
bookWidth = pageWidth / 2;
|
||||
bookX = (pageWidth - bookWidth) / 2;
|
||||
}
|
||||
|
||||
const int bookHeight = baseHeight;
|
||||
constexpr int bookY = 30;
|
||||
const bool bookSelected = hasContinueReading && selectorIndex == 0;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user