Forum: Projekte & Code Bitmap Konverter


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Hagen R. (hagen)


Angehängte Dateien:

Lesenswert?

Anbei eine Beta meines Konverters.

Vorerst müsste das Exportieren in das RAW Format ausreichend sein. Dazu 
einfach die Checkbox "RAM Data" anhacken und es wird eine C Header Datei 
gespeichert in der die Pixel mit 16Bit Farbwerten codiert sind.

Für die anderen 3 Datenformate die ich verwende kann ich noch 
Erklärungen und Beispielcode in C nachliefern, wenn gewünscht. Vorerst 
nur mal par Stichpunkte was drinnen ist:

- 1 Farb Bitmaps, das sind nichts anderes als mit einer Farbe 
ausgefüllte Rechtecke, quasi leere Bitmaps mit einer Hintergrundfarbe

- 16 Bit Bitmaps, das sind unkomprimierte Bitmaps in voller Farbe, 
meistens weil eine Komprimierung nichts bringt

- Monochrome Bitmaps (2 Farben) mit Komprimierung. Die Daten sind per 
RLE komprimiert und man erreicht ca. 2000-3000% Packungsrate im 
Vergleich zu RAW

- 2 Bit bis 15 Bit Farbbitmaps, also von 3 Farben bis 32765 Farben. Die 
Daten sind komprimiert und benutzen eine Farbtabelle. Die 
Komprimierungsrate ist fast immer besser als bei PNG Bildern. Wichtig 
ist das man nur durchschnittlich 16 AVR Takte pro Datenbyte in den 
Zeichenroutinen benötigt für diese Dekomprimierung. Man erreicht also 
defakto den maximalen Datendurchsatz bei 8Mhz SPI auf einem 16Mhz AVR, 
direkt aus dem FLASH ohne zusätzlichen SRAM zu verbrauchen.


Die Software selber kann
- PNG, BMP, WMF, EMF, ICO, JPEG laden
- in beliebigem Farbformat
- in beliebiger Größe
- das Bild wird runter skaliert auf maximal 176x132 Pixeln wenn nötig, 
Seitenverhältnis wird beibehalten
- die Farbpalette/-anzahl kann reduziert werden
- das Bild kann in 90 Gradschritte rotiert, und gespiegelt werden


Gruß Hagen

Ausschnitt meines bisherigen Codes für meine S65-GLCD des LPH88xxx 
Display (Philips HD66773R Controller).
1
#include "glcd.h"
2
3
uint16_t colormasks[14] PROGMEM = {0x0006, 0x000E, 0x001E, 0x003E, 0x007E, 0x00FE, 0x01FE, 0x03FE, 0x07FE, 0x0FFE, 0x1FFE, 0x3FFE, 0x7FFE, 0xFFFE};
4
5
void glcdDrawBitmap(glcdCoord_t x, glcdCoord_t y, const prog_char* bitmap, uint8_t flags) {
6
7
8
#define GLCD_LOAD_BITS(data0, data2, databits, addr, bitsmul) \
9
   asm volatile(                            \
10
    "cpi   %2, lo8(16)"         "\n\t"  \
11
        "brsh  .%=2"                "\n\t"  \
12
        "movw  r30, %A3"            "\n\t"  \
13
        "lpm   r0, Z+"              "\n\t"  \
14
        "mul   r0, %4"              "\n\t"  \
15
        "cpi   %2, lo8(8)"          "\n\t"  \
16
        "brsh  .%=1"                "\n\t"  \
17
        "or    %A0, r0"             "\n\t"  \
18
        "or    %B0, r1"             "\n\t"  \
19
        "subi  %2, lo8(-(8))"       "\n\t"  \
20
        "lpm   r0, Z+"              "\n\t"  \
21
        "mul   r0, %4"              "\n\t"  \
22
".%=1:"                             "\n\t"  \
23
        "or    %B0, r0"             "\n\t"  \
24
        "or    %1, r1"              "\n\t"  \
25
        "subi  %2, lo8(-(8))"       "\n\t"  \
26
        "movw  %A3, r30"            "\n\t"  \
27
".%=2:"                             "\n\t"  \
28
        "clr   r1"                  "\n\t"  \
29
      : "=r" (data0),                     \
30
        "=r" (data2),                     \
31
        "=a" (databits),                  \
32
        "=r" (addr),                      \
33
        "=r" (bitsmul)                    \
34
      : "r" (data0),                      \
35
        "r" (data2),                      \
36
        "a" (databits),                   \
37
        "r" (addr),                       \
38
        "r" (bitsmul)                     \
39
        : "r0", "r1", "r30", "r31"          \
40
     );
41
42
#define GLCD_LOAD_COLOR(data0, data2, databits, colortable, colormask, bpp, bitsmul, bkcolor) \
43
   asm volatile(                            \
44
        "movw  r30, %A0"            "\n\t"  \
45
        "lsr   %1"                  "\n\t"  \
46
        "ror   %B0"                 "\n\t"  \
47
        "ror   %A0"                 "\n\t"  \
48
        "brcs  .%=0"                "\n\t"  \
49
        "dec   %2"                  "\n\t"  \
50
        "lsr   %6"                  "\n\t"  \
51
        "brne  .%=3"                "\n\t"  \
52
        "ori   %6, lo8(0x80)"       "\n\t"  \
53
        "rjmp  .%=3"                "\n\t"  \
54
".%=0:"                             "\n\t"  \
55
        "and   r30, %A4"            "\n\t"  \
56
        "and   r31, %B4"            "\n\t"  \
57
        "add   r30, %A3"            "\n\t"  \
58
        "adc   r31, %B3"            "\n\t"  \
59
        "lpm   %A7, Z+"             "\n\t"  \
60
        "lpm   %B7, Z"              "\n\t"  \
61
        "mov   r30, %5"             "\n\t"  \
62
        "cpi   r30, lo8(8)"         "\n\t"  \
63
        "brlo  .%=1"                "\n\t"  \
64
        "mov   %A0, %B0"            "\n\t"  \
65
        "mov   %B0, %1"             "\n\t"  \
66
        "clr   %1"                  "\n\t"  \
67
        "andi  r30, lo8(0x07)"      "\n\t"  \
68
        "breq  .%=2"                "\n\t"  \
69
".%=1:"                             "\n\t"  \
70
        "lsr   %1"                  "\n\t"  \
71
        "ror   %B0"                 "\n\t"  \
72
        "ror   %A0"                 "\n\t"  \
73
        "dec   r30"                 "\n\t"  \
74
        "brne  .%=1"                "\n\t"  \
75
".%=2:"                             "\n\t"  \
76
        "sub   %2, %5"              "\n\t"  \
77
        "dec   %2"                  "\n\t"  \
78
        "mov   r30, %2"             "\n\t"  \
79
        "andi  r30, lo8(0x07)"      "\n\t"  \
80
        "clr   r31"                 "\n\t"  \
81
        "subi  r30, lo8(-(powerof2))"   "\n\t"  \
82
        "sbci  r31, hi8(-(powerof2))"   "\n\t"  \
83
        "lpm   %6, Z"               "\n\t"  \
84
".%=3:"                             "\n\t"  \
85
      : "=r" (data0),                     \
86
        "=r" (data2),                     \
87
        "=a" (databits),                  \
88
        "=r" (colortable),                \
89
        "=r" (colormask),                 \
90
        "=r" (bpp),                       \
91
        "=r" (bitsmul),                   \
92
        "=r" (bkcolor)                    \
93
      : "r" (data0),                      \
94
        "r" (data2),                      \
95
        "a" (databits),                   \
96
        "r" (colortable),                 \
97
        "r" (colormask),                  \
98
        "r" (bpp),                        \
99
        "r" (bitsmul),                    \
100
        "r" (bkcolor)                     \
101
        : "r30", "r31"                      \
102
     );
103
104
105
    if (!(bitmap)) return;
106
    uint8_t w = pgm_read_byte_inc(bitmap);
107
    if (!(w)) return;
108
    uint8_t h = pgm_read_byte_inc(bitmap);
109
    if (!(h)) return;
110
    uint8_t bpp = pgm_read_byte_inc(bitmap);
111
    uint16_t bkcolor = pgm_read_word_inc(bitmap);
112
    if (flags & GLCD_BMP_USECOLORS) bkcolor = glcd.Colors[0];
113
    if (bpp == 0) {
114
      glcdFillRect(x, y, x + w -1, y + h -1, bkcolor);
115
      return;
116
    }
117
    GLCD_CS_ON();
118
    GLCD_SETADDR(x, y);
119
    GLCD_WINDOW(x, y, x + w -1, y + h -1);
120
    if (flags & GLCD_BMP_TRANSPARENT) {
121
      GLCD_SETMODE(0x38 | GLCD_ROP_WNE);
122
      GLCD_SETCOMPARE(bkcolor);
123
    } else {
124
      GLCD_SETMODE(0x38);
125
    }
126
    GLCD_STARTDATA();
127
    if (bpp == 1) {// monochrome
128
      uint16_t pixelcount = w * h;
129
      uint16_t fgcolor = pgm_read_word_inc(bitmap);
130
      if (flags & GLCD_BMP_USECOLORS) fgcolor = glcd.Colors[1];
131
      uint16_t color = bkcolor;
132
      if (flags & GLCD_BMP_SWAPCOLORS) {
133
        bkcolor = fgcolor;
134
        fgcolor = color;
135
        color   = bkcolor;
136
      }
137
      uint8_t data = pgm_read_byte_inc(bitmap);
138
      uint8_t pixelbits = ((data >> 4) +1) << 2;
139
      data &= 0x0F;
140
      uint8_t temp = data << 4;
141
      data |= temp;
142
      do {
143
        GLCD_WAIT();
144
        GLCD_OUT(H8(color));
145
        if (!(--pixelbits)) {
146
          data = pgm_read_byte_inc(bitmap);
147
          pixelbits = ((data >> 4) +1) << 2;
148
          data &= 0x0F;
149
          uint8_t temp = data << 4;
150
          data |= temp;
151
        }
152
        GLCD_WAIT();
153
        GLCD_OUT(L8(color));
154
        ROL(data);                                // rotate data, data = (data << 1) | (data >> 7);
155
        color = bkcolor;
156
        if (data & 0x01) color = fgcolor;
157
      } while (--pixelcount);
158
    } else if (bpp == 16) { // full color
159
      uint16_t pixelcount = w * h;
160
      while (pixelcount) {
161
        GLCD_WAIT();
162
        GLCD_OUT(H8(bkcolor));
163
        pixelcount--;
164
        GLCD_WAIT();
165
        GLCD_OUT(L8(bkcolor));
166
        bkcolor = pgm_read_word_inc(bitmap);
167
      }
168
    } else {// color, 2 upto 15 BPP
169
      uint16_t colortablesize = pgm_read_word_inc(bitmap);
170
      uint8_t* colortable = (uint8_t*)bitmap;
171
      bitmap += colortablesize;
172
      uint16_t colormask = pgm_read_word(&colormasks[bpp -2]);
173
      uint8_t databits = 0, data2 = 0, bitsmul = 1;
174
      uint16_t data0 = 0;
175
//      uint32_t data = 0;
176
      uint16_t pixelcount = w * h;
177
      do {
178
        GLCD_WAIT();
179
        GLCD_OUT(H8(bkcolor));
180
        pixelcount--;
181
        GLCD_LOAD_BITS(data0, data2, databits, bitmap, bitsmul);
182
183
//        while (databits < 16) {
184
//          uint16_t t = pgm_read_byte_inc(bitmap) * bitsmul;
185
//          if (databits >= 8) data |= (uint32_t)t << 8;
186
//            else data |= t;
187
//          databits += 8;
188
//        }
189
190
        GLCD_WAIT();
191
        GLCD_OUT(L8(bkcolor));
192
193
        GLCD_LOAD_COLOR(data0, data2, databits, colortable, colormask, bpp, bitsmul, bkcolor);
194
195
//        if (LL8(data) & 0x01) {
196
//          bkcolor = pgm_read_word(colortable + (L16(data) & colormask));
197
//          data >>= bpp;
198
//          databits -= bpp;
199
//          bitsmul = pgm_read_byte(&powerof2[databits & 0x07]);
200
//        }
201
//        bitsmul >>= 1;
202
//        if (!(bitsmul)) bitsmul |= 0x80;
203
//        data >>= 1;
204
//        databits--;
205
      } while (pixelcount);
206
    }
207
    GLCD_WAIT();
208
    GLCD_CS_PULSE();
209
    GLCD_SETMODE(0x30);
210
    GLCD_CS_OFF();
211
}

  

von Michele B. (luxx) Benutzerseite


Lesenswert?

super sache! vielen dank!

von Hagen R. (hagen)


Lesenswert?

Sorry, dieser Beitrag sollte hier eigentlich garnicht landen. Könnte 
aber auch seine Vorteile haben einen extra Thread abzuspalten.

Es geht um eine PC Software die Bilder auf dem PC so bearbeitet und 
konvertiert das man sie auf den S65 Displays benutzen kann.

Gruß Hagen

von Franz (Gast)


Lesenswert?

Hallo,

super Programm - kann ich das auch für andere Bildgrößen kriegen?

von Richard (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

versuche gerade ein kleines Bitmap (10x10 Pixel) auf meinem S65 LCD 
darzustellen. Habe den Converter von Hagen Re benutzt um die Bilddaten 
als raw data in einem array zu speichern. Das Bild im Anhang möchte ich 
gerne darstellen lassen. Zu sehen ist aber nur ein bunter Pixelhaufen. 
So sehen die raw daten des Bildes aus:
1
uint8_t img_bmp[] PROGMEM = 
2
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 
3
  0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
4
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 
5
  0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
6
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 
7
  0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
8
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 
9
  0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
10
  0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 
11
  0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 
12
  0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 
13
  0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 
14
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 
15
  0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
16
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 
17
  0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
18
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 
19
  0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
20
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 
21
  0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

Und das sind die Routinen für die Bildwiedergabe von Christian Kranz:
1
void LCD_WrData(unsigned char data)
2
{
3
 CLR(LCD_CS);          
4
 CLR(LCD_RS);          
5
 SPDR = data;
6
 while(!(SPSR & (1<<SPIF)));
7
 SET(LCD_CS);
8
}
9
10
void S65_wrcmd16(uint16_t dat)
11
{
12
 LCD_WrCmd((dat>>8));
13
 LCD_WrCmd(dat);
14
}
15
16
void S65_allocatearea(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
17
{
18
 uint8_t x, y;
19
 if(x1 < x2)
20
 { 
21
  x = x2; 
22
  x2 = x1; 
23
  x1 = x;
24
 }
25
 if(y2 < y1)
26
 { 
27
  y = y1; 
28
  y1 = y2; 
29
  y2 = y;
30
 }
31
 S65_wrcmd16(0xEF80);    
32
 S65_wrcmd16(0x1805);
33
 S65_wrcmd16(0x1200 + x1);  
34
 S65_wrcmd16(0x1500 + x2);
35
 S65_wrcmd16(0x1300 + y1);  
36
 S65_wrcmd16(0x1600 + y2);
37
}
38
39
void S65_PutRawBmp16(uint8_t x, uint8_t y, uint8_t *pic, uint8_t w, uint8_t h)
40
{
41
 uint8_t dimx = w-1; 
42
 uint8_t dimy = h-1;
43
 S65_allocatearea(x, y, x+dimx, y+dimy);
44
  
45
 for(uint16_t counter = 0; counter < ((dimx+1)*(dimy+1))*2; counter++)
46
 {
47
  LCD_WrData(pgm_read_byte_near(&pic[counter]));
48
 }
49
}

Wird dann in der main() so aufgerufen:
1
S65_PutRawBmp16(60, 60, img_bmp, 10, 10);

Ich betreibe das Display an einem ATmega644 bei 16MHz. Die Wiedergabe 
von Text funktioniert bereits. Nur mit dem Bild habe ich Probleme.

Wer hat einen Tipp für mich?
Gruß
Richard

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.