mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2025-12-18 07:07:41 +03:00
rotate fullscreen bmp CCW instead of CW
This commit is contained in:
parent
602d3da3a2
commit
d60378719c
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,4 @@
|
||||
.pio
|
||||
.idea
|
||||
.DS_Store
|
||||
.vscode
|
||||
.vscode
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
uint16_t BmpToMono::readLE16(fs::File& f) {
|
||||
uint16_t BmpToMono::readLE16(File& f) {
|
||||
const int c0 = f.read();
|
||||
const int c1 = f.read();
|
||||
const uint8_t b0 = (uint8_t)(c0 < 0 ? 0 : c0);
|
||||
@ -11,7 +11,7 @@ uint16_t BmpToMono::readLE16(fs::File& f) {
|
||||
return (uint16_t)b0 | ((uint16_t)b1 << 8);
|
||||
}
|
||||
|
||||
uint32_t BmpToMono::readLE32(fs::File& f) {
|
||||
uint32_t BmpToMono::readLE32(File& f) {
|
||||
const int c0 = f.read();
|
||||
const int c1 = f.read();
|
||||
const int c2 = f.read();
|
||||
@ -67,15 +67,11 @@ const char* BmpToMono::errorToString(BmpToMonoError err) {
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
BmpToMonoError BmpToMono::convert24(fs::File& file, MonoBitmap& out, uint8_t threshold, bool invert) {
|
||||
return convert24Impl(file, out, threshold, invert, false);
|
||||
BmpToMonoError BmpToMono::convert24BitRotate90CCW(File& file, MonoBitmap& out, uint8_t threshold) {
|
||||
return convert24BitImpl(file, out, threshold, true);
|
||||
}
|
||||
|
||||
BmpToMonoError BmpToMono::convert24Rotate90CW(fs::File& file, MonoBitmap& out, uint8_t threshold, bool invert) {
|
||||
return convert24Impl(file, out, threshold, invert, true);
|
||||
}
|
||||
|
||||
BmpToMonoError BmpToMono::convert24Impl(fs::File& f, MonoBitmap& out, uint8_t threshold, bool invert, bool rotate90CW) {
|
||||
BmpToMonoError BmpToMono::convert24BitImpl(File& f, MonoBitmap& out, uint8_t threshold, bool rotate90CCW) {
|
||||
freeMonoBitmap(out);
|
||||
|
||||
if (!f) return BmpToMonoError::FileInvalid;
|
||||
@ -117,8 +113,8 @@ BmpToMonoError BmpToMono::convert24Impl(fs::File& f, MonoBitmap& out, uint8_t th
|
||||
if (srcH <= 0) return BmpToMonoError::BadDimensions;
|
||||
|
||||
// Output dimensions
|
||||
out.width = rotate90CW ? (int)srcH : (int)srcW;
|
||||
out.height = rotate90CW ? (int)srcW : (int)srcH;
|
||||
out.width = rotate90CCW ? (int)srcH : (int)srcW;
|
||||
out.height = rotate90CCW ? (int)srcW : (int)srcH;
|
||||
|
||||
const size_t outBytesPerRow = (size_t)(out.width + 7) / 8;
|
||||
out.len = outBytesPerRow * (size_t)out.height;
|
||||
@ -158,16 +154,15 @@ BmpToMonoError BmpToMono::convert24Impl(fs::File& f, MonoBitmap& out, uint8_t th
|
||||
|
||||
const uint8_t lum = (uint8_t)((77u * r + 150u * g + 29u * b) >> 8);
|
||||
bool isBlack = (lum < threshold);
|
||||
if (invert) isBlack = !isBlack;
|
||||
|
||||
int outX, outY;
|
||||
if (!rotate90CW) {
|
||||
if (!rotate90CCW) {
|
||||
outX = srcX;
|
||||
outY = srcY;
|
||||
} else {
|
||||
// 90° clockwise: (x,y) -> (h-1-y, x)
|
||||
outX = (int)srcH - 1 - srcY;
|
||||
outY = srcX;
|
||||
// 90° counter-clockwise: (x,y) -> (y, w-1-x)
|
||||
outX = srcY;
|
||||
outY = (int)srcW - 1 - srcX;
|
||||
}
|
||||
|
||||
setMonoPixel(out.data, out.width, outX, outY, isBlack);
|
||||
|
||||
@ -32,20 +32,16 @@ enum class BmpToMonoError : uint8_t {
|
||||
|
||||
class BmpToMono {
|
||||
public:
|
||||
// No rotation: output size == BMP size
|
||||
static BmpToMonoError convert24(fs::File& file, MonoBitmap& out, uint8_t threshold = 160, bool invert = false);
|
||||
|
||||
// Rotate 90° clockwise: (w,h) -> (h,w)
|
||||
// Useful for converting portrait BMP (480x800) into landscape framebuffer (800x480).
|
||||
static BmpToMonoError convert24Rotate90CW(fs::File& file, MonoBitmap& out, uint8_t threshold = 160,
|
||||
bool invert = false);
|
||||
// Rotate 90° counter-clockwise: (w,h) -> (h,w)
|
||||
// Used for converting portrait BMP (480x800) into landscape framebuffer (800x480)
|
||||
static BmpToMonoError convert24BitRotate90CCW(File& file, MonoBitmap& out, uint8_t threshold = 160);
|
||||
|
||||
static void freeMonoBitmap(MonoBitmap& bmp);
|
||||
static const char* errorToString(BmpToMonoError err);
|
||||
|
||||
private:
|
||||
static uint16_t readLE16(fs::File& f);
|
||||
static uint32_t readLE32(fs::File& f);
|
||||
static uint16_t readLE16(File& f);
|
||||
static uint32_t readLE32(File& f);
|
||||
|
||||
// Writes a single pixel into a row-aligned 1bpp buffer (MSB-first), 0=black, 1=white
|
||||
static inline void setMonoPixel(uint8_t* buf, int w, int x, int y, bool isBlack) {
|
||||
@ -58,5 +54,5 @@ class BmpToMono {
|
||||
buf[idx] |= mask;
|
||||
}
|
||||
|
||||
static BmpToMonoError convert24Impl(fs::File& file, MonoBitmap& out, uint8_t threshold, bool invert, bool rotate90CW);
|
||||
static BmpToMonoError convert24BitImpl(File& file, MonoBitmap& out, uint8_t threshold, bool rotate90CW);
|
||||
};
|
||||
@ -129,8 +129,8 @@ bool GfxRenderer::drawFullScreenBmp(File& file) {
|
||||
|
||||
file.seek(0); // Ensure we're at the start of the file
|
||||
|
||||
MonoBitmap mono;
|
||||
auto err = BmpToMono::convert24Rotate90CW(file, mono, 160, false);
|
||||
MonoBitmap bmp;
|
||||
auto err = BmpToMono::convert24BitRotate90CCW(file, bmp);
|
||||
|
||||
if (err != BmpToMonoError::Ok) {
|
||||
Serial.printf("[%lu] [GFX] BMP convert failed: %s\n", millis(), BmpToMono::errorToString(err));
|
||||
@ -138,17 +138,17 @@ bool GfxRenderer::drawFullScreenBmp(File& file) {
|
||||
}
|
||||
|
||||
// Hard requirement: must match panel exactly
|
||||
if (mono.width != EInkDisplay::DISPLAY_WIDTH || mono.height != EInkDisplay::DISPLAY_HEIGHT) {
|
||||
if (bmp.width != EInkDisplay::DISPLAY_WIDTH || bmp.height != EInkDisplay::DISPLAY_HEIGHT) {
|
||||
Serial.printf("[%lu] [GFX] drawFullScreenBmp: rotated BMP size %dx%d does not match panel %dx%d\n", millis(),
|
||||
mono.width, mono.height, EInkDisplay::DISPLAY_WIDTH, EInkDisplay::DISPLAY_HEIGHT);
|
||||
BmpToMono::freeMonoBitmap(mono);
|
||||
bmp.width, bmp.height, EInkDisplay::DISPLAY_WIDTH, EInkDisplay::DISPLAY_HEIGHT);
|
||||
BmpToMono::freeMonoBitmap(bmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Raw full-screen blit
|
||||
einkDisplay.drawImage(mono.data, 0, 0, mono.width, mono.height);
|
||||
// Full-screen blit
|
||||
einkDisplay.drawImage(bmp.data, 0, 0, bmp.width, bmp.height);
|
||||
|
||||
BmpToMono::freeMonoBitmap(mono);
|
||||
BmpToMono::freeMonoBitmap(bmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user