lovyan03 / LovyanGFX

SPI LCD graphics library for ESP32 (ESP-IDF/ArduinoESP32) / ESP8266 (ArduinoESP8266) / SAMD51(Seeed ArduinoSAMD51)
Other
1.03k stars 189 forks source link

Pay more attention to greyscale bitmaps and sprites. #461

Closed fsender closed 5 months ago

fsender commented 6 months ago

There are 3 different issues. I'm developing a library for E-paper displays. It supports 16-level grey display for most common E-paper displays. I hope you can pay more attention to greyscale bitmaps and sprites.

Firstly. Setting buffer for static greyscale bitmaps.

I tried using setBuffer function for my static 8-bpp greyscale bitmap array. Bit it was always converted to RGB332 colour format. Now I have to edit your library to show a static greyscale bitmap.

Now there is an available function prototype for setBuffer at file LGFX_Sprite.hpp line 155.

    void setBuffer(void* buffer, int32_t w, int32_t h, uint8_t bpp = 0);

Could you add a function like this?

    void setBuffer(void* buffer, int32_t w, int32_t h, color_depth_t bpp = rgb565_2Byte)
    {
      deleteSprite();
      if (bpp != 0) {
        _write_conv.setColorDepth(bpp);
        _read_conv = _write_conv;
        _panel_sprite.setColorDepth(bpp);
      }

      _panel_sprite.setBuffer(buffer, w, h, &_write_conv);
      _img = _panel_sprite.getBuffer();

      _sw = w;
      _clip_r = w - 1;
      _xpivot = w >> 1;

      _sh = h;
      _clip_b = h - 1;
      _ypivot = h >> 1;
    }

Next. My ESP32 Halted when copying from an RGB sprite to a 4bpp greyscale sprite.

When copying from an RGB565 or RGB888 sprite to a grey bitmap (1bpp, 2bpp and 4bpp) the library halted at file LGFX_Sprite.cpp line 481: in void Panel_Sprite::writeImage(uint_fast16_t x, uint_fast16_t y, uint_fast16_t w, uint_fast16_t h, pixelcopy_t* param, bool) fp_copy is nullptr.

my destination sprite is greyscale 4bit color type. Source sprite is RGB565 color type.

I have tried these: source destination result
RGB565 RGB332 OK
RGB565 8bit Greyscale OK
RGB888 8bit Greyscale OK
RGB332 8bit Greyscale OK
8bit Greyscale 8bit Greyscale OK
4bit Greyscale 8bit Greyscale OK
2bit Greyscale 8bit Greyscale OK
1bit Greyscale 8bit Greyscale OK
2bit palette 8bit Greyscale OK
RGB565 4bit Greyscale NG
RGB888 4bit Greyscale NG
RGB332 4bit Greyscale NG
8bit Greyscale 4bit Greyscale NG
4bit Greyscale 4bit Greyscale NG
1bit Greyscale 4bit Greyscale NG
2bit palette 4bit Greyscale NG
RGB565 2bit Greyscale NG
RGB565 1bit Greyscale NG
RGB565 2bit palette NG
RGB565 1bit palette NG

At file pixelcopy.hpp line 115.

    template<typename TSrc>
    static auto get_fp_copy_rgb_affine(color_depth_t dst_depth) -> uint32_t(*)(void*, uint32_t, uint32_t, pixelcopy_t*)
    {
      return (dst_depth == rgb565_2Byte) ? copy_rgb_affine<swap565_t, TSrc>
           : (dst_depth == rgb332_1Byte) ? copy_rgb_affine<rgb332_t , TSrc>
           : (dst_depth == rgb888_3Byte) ? copy_rgb_affine<bgr888_t, TSrc>
           : (dst_depth == rgb666_3Byte) ? (std::is_same<bgr666_t, TSrc>::value
                                           ? copy_rgb_affine<bgr888_t, bgr888_t>
                                           : copy_rgb_affine<bgr666_t, TSrc>)
           : (dst_depth == grayscale_8bit) ? copy_rgb_affine<grayscale_t, TSrc>
           : nullptr;
    }

I think this nullptr is the reason. Please add pixel copying support for 1bpp,2bpp and 4bpp bitmaps and sprites.


Finally.

Why do not you add a method to get the width and the height of an image? Even if the image is a file or a web url. Some projects need it. The function prototype may be like this below:

bool getWidthHeightBmp(DataWrapper* data, int32_t *width, int32_t *height);
bool getWidthHeightBmp(const uint8_t *data, uint32_t len, int32_t *width, int32_t *height);
bool getWidthHeightBmpUrl(const char *url, int32_t *width, int32_t *height);
bool getWidthHeightBmpFile(fs::FS &Fs, fs::File *file, int32_t *width, int32_t *height);
bool getWidthHeightBmpFile(fs::FS &Fs, const char *path, int32_t *width, int32_t *height);
bool getWidthHeightJpgFile(fs::FS &Fs, const char *path, int32_t *width, int32_t *height);
bool getWidthHeightPngFile(fs::FS &Fs, const char *path, int32_t *width, int32_t *height);
bool getWidthHeightQoiFile(fs::FS &Fs, const char *path, int32_t *width, int32_t *height);

Thanks.

github-actions[bot] commented 5 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] commented 5 months ago

This issue has been automatically closed because it has not had recent activity. Thank you for your contributions.

fsender commented 2 months ago

/reopen