olikraus / ucglib

Arduino True Color Library for TFTs and OLEDs
https://github.com/olikraus/ucglib/wiki
Other
261 stars 76 forks source link

Creating small bitmap on Ucglib #130

Open macste7 opened 4 years ago

macste7 commented 4 years ago

Hi I have problem with creating bitmap on 1.8 tft display (red pcb) and bdfconv doesn't work :( I have no idea how to make it. I will be very thankful if you help me 👍

a-v-s commented 4 years ago

Open the image with The Gimp and save as C source code. Then loop through the pixel data and write them pixel for pixel.

typedef struct {
    uint8_t r;
    uint8_t g;
    uint8_t b;
    uint8_t a;
} rgba_t;
     for (int y = 0; y < gimp_image.heigth y++) {
         for (int x = 0; x < gimp_image.width; x++) {
             rgba_t* pixel = gimp_image.pixel_data + count ;
             ucg_SetColor(&m_ucg, 0, pixel->r, pixel->g, pixel->b);
             ucg_DrawPixel(&m_ucg,x,y);
             count += gimp_image.bytes_per_pixel;
         }
     }
macste7 commented 4 years ago

But there is no easier way to create bitmap ?

a-v-s commented 4 years ago

I can't imagine an easier way then for loops.

MBENKI commented 3 years ago

Open the image with The Gimp and save as C source code. Then loop through the pixel data and write them pixel for pixel.

typedef struct {
  uint8_t r;
  uint8_t g;
  uint8_t b;
  uint8_t a;
} rgba_t;
   for (int y = 0; y < gimp_image.heigth y++) {
       for (int x = 0; x < gimp_image.width; x++) {
           rgba_t* pixel = gimp_image.pixel_data + count ;
           ucg_SetColor(&m_ucg, 0, pixel->r, pixel->g, pixel->b);
           ucg_DrawPixel(&m_ucg,x,y);
           count += gimp_image.bytes_per_pixel;
       }
   }

Hi @a-v-s , thank you for the suggestion, i have the same problem, i exported a logo as a .h file (okone.h), i want to display it using Ucglib library of course), i a m a beginner in this matter, and i would like to ask you how i should include the image in my code. i actually created a lighter library i called printucg240 where i use only two functions (i include this library in my main sketch that i use for a scale and i display the weight on a 2.4 240*320 ILI9341 screen), i have already integrated the two for loops but i don't know how to write it correctly here's the code below :

  `#include "printucg240.h"
  #include <Ucglib.h>
  #include "okone.h"

  Ucglib_ILI9341_18x240x320_SWSPI ucg240(/*sclk=*/ 13, /*data=*/ 11, /*cd=*/ 9, /*cs=*/ 10, /*reset=*/ 8);

  void drawLogo240() {
    typedef struct {
      uint8_t r;
      uint8_t g;
      uint8_t b;
      uint8_t a;
    } rgba_t;
    float count = 0;
    for (int y = 0; y < okone.height; y++) {
      for (int x = 0; x < okone.width; x++) {
        rgba_t* pixel = okone.pixel_data + count ;
        ucg240.setColor(0, pixel->r, pixel->g, pixel->b);
        ucg240.drawPixel(x,y);
        count += okone.bytes_per_pixel;
      }
    }
    delay(5500);
  }

  void draw240(String text, int milsecs) { 
    ucg240.begin(UCG_FONT_MODE_TRANSPARENT);
    ucg240.setRotate90(); 
    ucg240.setFontPosCenter();
    ucg240.setFont(ucg_font_profont29_mf);
    ucg240.setColor(255, 255, 255);
    ucg240.setPrintPos(20, 120);
    ucg240.print(text);
    delay(milsecs);
  }

  void drawWeight240(String text, int milsecs) { 
    ucg240.begin(UCG_FONT_MODE_TRANSPARENT);
    ucg240.setRotate90();
    ucg240.setFontPosCenter();
    ucg240.setFont(ucg_font_inb33_tr);
    ucg240.setColor(255, 255, 255);
    ucg240.setPrintPos(80, 120);
    ucg240.print(text + "g");
    delay(milsecs);
  }

`

I would be very grateful if you could help me , thank you very much @a-v-s

TCB13 commented 3 years ago
rgba_t* pixel = gimp_image.pixel_data + count ;

How is this valid code?

TD-er commented 3 years ago
rgba_t* pixel = gimp_image.pixel_data + count ;

How is this valid code?

Looks just like basic pointer arithmetic. Just create a pointer to the start of pixel_data and offset it count elements from the start. (so not bytes, but sizeof(rgba_t) )

TCB13 commented 1 year ago

Looks just like basic pointer arithmetic.

Still doesn't compile: Cannot initialize a variable of type 'rgba_t *' with an rvalue of type 'const char *'. Does anyone have a working example of this?

Since we're on the subject, what about storing and retrieving the image on and from PROGMEM?

TCB13 commented 1 year ago

Just adding this for future reference: https://www.linux.org/threads/how-to-read-a-c-source-file-into-a-array.11104/#post-38289

a-v-s commented 1 year ago

Looks just like basic pointer arithmetic.

Still doesn't compile: Cannot initialize a variable of type 'rgba_t *' with an rvalue of type 'const char *'. Does anyone have a working example of this?

Since we're on the subject, what about storing and retrieving the image on and from PROGMEM?

It looks like you are using C++, whereas I was using C. Casting in C++ has to be a bit more explicit then in C. So make it

rgba_t* pixel = (rgba_t*)(gimp_image.pixel_data + count );

and the compiler should stop complaining about that.

Furthermore, I'd recommend to put a

#pragma pack(push,1)
typedef struct {
    uint8_t r;
    uint8_t g;
    uint8_t b;
    uint8_t a;
} rgba_t;
#pragma pack(pop)

to ensure the compiler doesn't pad the members of the struct.

a-v-s commented 1 year ago

Since we're on the subject, what about storing and retrieving the image on and from PROGMEM?

PROGMEM? Sounds like something AVR specific. Unfortunately I have little experience on that platform. I've read some gcc documentation about address spaces, specifically, __memx which linearises address space making such easier, but unfortunately, that is C only, not supported in C++.