Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Konstrukcja bitmapy + program bmp2bascom

30 Sty 2010 16:14 4423 41
  • Poziom 26  
    Witam,
    Jako, że przymierzam się do wyświetlenia prostych bitmap na lcd kolorowym zainteresował mnie jeden aspekt specyfikacji pliku BMP. Otóż, jeśli ten plik zawiera obraz o innej niż 24bpp liczbie kolorów to znajduje się w nim, po nagłówku, informacja o palecie (w zasadzie używana paleta kolorów). Zastanawiam się w jakim celu skoro później, po tej palecie, w pliku i tak zawarta jest informacja o składowych RGB każdego z pikseli? Z resztą, jak taki plik BMP przekonwertujemy na format RAW (czyli czyste dane samego obrazu, składowe RGB) to i tak tracimy tą, jak się wydaje niepotrzebną, informcję o plaecie kolorów. Więc po co ta paleta? Swoją drogą to może znacie jakiś prosty programik, który od razu zamieni dane zawarte w pliku BMP na reprezentację HEX, którą można dołączyć do kodu programu - wiem, wiem, marnotrastwo flasha. Można by ewentualnie implementowac jakiś algorytm kompresji, choćby RLE8... robiw
  • Użytkownik usunął konto  
  • Poziom 26  
    Strukturę znam i stąd pytanie. 256 odcieni zielonego uzyskasz tak czy inaczej na 8 bitach koloru G :-) więc po co ta paleta to nie wiem - paleta występuje wyłącznie wtedy, gdy liczba kolorów jest inna niż 24bpp...robiw
  • Poziom 25  
    robiw sam sobie przecież już odpowiedziałeś :)
    Jeżeli paleta kolorów jest inna niż 24bpp to z kąd wiesz że 2 obrazki ściągnięte z neta są w tych samych odcieniach kolorów? Chodzi o to, że jak masz program i np 2 obrazki i chcesz je wyświetlić jednocześnie, to palety kolorów muszą być identyczne, co by zielony był równy zielonemu :)

    Różne obrazki mogą mieć różna paletę (pod warunkiem że mniej niż 24bpp), więc z reguły robi się to tak że komplet obrazków które chcesz wykorzystać w swoim projekcie musisz skonwertować do jednej palety, no chyba że nie bierzesz pod uwagę sytuacji w której wyświetlasz 2 obrazki jednocześnie.
  • Poziom 26  
    Kurczę, nie jarzę. Załóżmy, że mam obrazek z kolorem 8bpp (czyli 256 kolorów). Format danych koloru dla tego typu to 3-3-2 czyli 3 bity na Red, 3 bity na Green i 2 bity na Blue. Po co nam paleta skoro w bajcie danych konkretnego pixela zawarta jest informacja o jego kolorze? No chyba, że założymy, iż ktoś zastosował np. format zapisu tego bajta 3-2-3 to wtedy jest skucha... To może być jedynie jakaś logiczna odpowiedź ;-). Wtedy potrzebna jest ta paleta ale ona przecież musi mieć inny zapis byśmy znowu mieli pewność jaki był jej format zapisu :|. Wtedy wystarczyłoby jako info o kolorze pixela podać jedynie indeks do palety...czyli sama tablica musi być w kolorze 24bpp...a tak nie jest... juz sam nie wiem...robiw
  • Poziom 34  
    W obrazku 24bpp każdy pixel jest opisany 24 bitami - możliwy do uzyskania jest każdy kolor. Przy 8bpp z paletą na każdy pixel przypada 8 bitów, ale służą one jako indeks do tablicy 256 elementów(palety), gdzie każdy element zawiera już pełny 24 bitowy kolor. Jeśli paleta będzie miała kolejne wartości od białego do czarnego, to obrazek będzie w skali szarości, zmieniając samą paletę da się z obrazka zrobić skalę zielonego, tęczę, negatyw - po prostu zamieniając mapowanie kolorów.
  • Poziom 26  
    Witam,
    No teraz to jasne :-)
    BoskiDialer napisał:
    W obrazku 24bpp każdy pixel jest opisany 24 bitami - możliwy do uzyskania jest każdy kolor...

    Z tym każdym to bym nie przesadzał ;-). Swoją drogą to muszę zastanowić się nad najszybszą formą wczytywania tych małych bimtapek. Pewnie skończy się na SD bo we flashu sporo się nie zmieści. Spotkaliście sie może ze wspomnianym wcześniej programem - BMP-> HEX lub coś podobnego? robiw
  • Poziom 43  
    Są w necie.
    Ja zwykle takie coś piszę sobie sam żeby można było łatwo modyfikować konwersję (np. dodawać przezroczystość albo zmieniać ilość bitów na kolor).
    Mogę wrzucić kod jednego z moich konwerterów. Ale exeka nie dam, bo mam chyba jakiś komponent do virusów w Delphi ;)
  • Poziom 26  
    atom1477 napisał:
    Są w necie.
    Ja zwykle takie coś piszę sobie sam żeby można było łatwo modyfikować konwersję (np. dodawać przezroczystość albo zmieniać ilość bitów na kolor).
    Mogę wrzucić kod jednego z moich konwerterów. Ale exeka nie dam, bo mam chyba jakiś komponent do virusów w Delphi ;)


    To poproszę jakiegoś konwertera bo przyznam, że nie bardzo chce mi się wracać do Delphi. Chciałbym bezpośrednio konwertować plik BMP w kolorze 24bpp na jakiś zjadliwy zapis HEX lub TXT - czyli kolejne składowe kolorów dla kolejnych pixeli najlepiej począwszy od górnego, lewego w dół. Fajnie by było by konwertował do 16bpp (format 5-6-5). Wiem, spore wymagania...robiw
  • Poziom 43  
    No to niestety ja nie pomogę. Napisać mogę w 3 minity, ale gotowców w necie to nie znam bo jeszcze przenigdy z nich nie korzystałem.
  • Poziom 26  
    atom1477 napisał:
    No to niestety ja nie pomogę. Napisać mogę w 3 minity, ale gotowców w necie to nie znam bo jeszcze przenigdy z nich nie korzystałem.


    Jeśli możesz to podeślij to co masz. Przebrnę przez to Delphi kolejny raz...robiw
  • Moderator Mikrokontrolery Projektowanie
    robiw, taki konwerter BMP->HEX juz zapewne masz. W jakim jezyku programujesz? W pakiecie WinAVR masz program avrobj-copy:
    http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_binarydata

    Tym konwertujesz dowolny plik binarny do pliku obj, ktory potem linker umieszcza w wynikowym pliku hex.
  • Poziom 26  
    No, niestety, rozczaruję Cię. Bascom ;-). Muszę chyba skrobnąć ten konwerter w Delphi bo sobie od razu kompresję zrobię by zaoszczędzić trochę flasha. Swoją drogą to rozumiem, że bajty w pliku bmp są zapisane w kolejności LSB...MSB, tak to przynajmniej wygląda? Ponadto każdy wiersz rysunku zajmuje wielokrotność 4 bajtów? robiw
  • Poziom 43  
    No ale nie rozumiem dlaczego nazywasz to "brnięciem". Przecież po prostu tylko to sobie skompilujesz. Ja nie mogę bo po mam jakiegoś virusa.
    No to masz. Program zapisuje to jako tablicę. Prosto do wklejenia w kod w C.
    Acha, i pierwsze dwa elementy w tej tablicy to rozdzielczość obrazka.
  • Moderator Mikrokontrolery Projektowanie
    robiw, RLE realizuje wiele programow graficznych, wystarczy zaznaczyc stosowna opcje, chyba nawet GIMP to ma, wiec niczego nie trzeba pisac. W dodatku zapisujesz to potem jako plik naglowkowy c, usuwasz z niego C-specyficzne rzeczy i zamieniasz na tablice bajtow, co pewnie Bascom lyknie. Sa tez inne wygodne narzedzia, ale skoro sobie wybrales Bascoma.... w dodatku chcesz za to placic to ja bym sie skontaktowal z supportem :P
  • Poziom 26  
    ...Bo za każdym razem miałem jakieś problemy z instalacją bibliotek Delphi i zapomniałem trochę składnię. Rozumiem, że to konwerter BMP ->HEX. Czy zapisuje tablicę już "normalnie" czyli pixele od lewej do prawej i od góry do dołu? Każdy pixel to 3 kolejne bajty R, G i B pomijając 2 pierwsze? Pozdrawiam i dzięki... robiw
  • Pomocny post
    Poziom 43  
    Zedytowałem post. Masz tam teraz konwerter do BASCOMa.
    Zapisuje od lewej do prawej a później przechodzi niżej. I znowu od lewej do prawej i przechodzi niżej.
    Zapisuje dane WORD w formacie 565.
  • Poziom 26  
    Serdeczne dzięki. W ten sposób nie muszę wracać do Delphi... choć lubiłem ten kompilator. Widzę, że skorzystałeś z kontrolki bitmapy co uprościło znacznie program. Rozumiem, że na wejściu jest bitmapa z kolorem 24bpp (program tego nie sprawdza) a na wyjściu jest plik z kolorem 16bpp w formacie R4R3R2R1R0G5G4G3G2G1G0B4B3B2B1B0 czyli 5-6-5 dla RGB przy czym pierwsze bajty (czy Word) to rozmiar obrazka... robiw

    PS.
    Swoją drogą fajnie i prosto to zrobiłeś. Ja zmieniłbym to jeszcze na typowy plik BIN tzn. pierwsze 4 bajty (nie dwa, tylko słowo Word na każdą z wielkości) to wymiary rysunku (szerokość i wysokość; MSB zawsze jako pierwszy) a kolejne bajty to słowa Word odpowiadające kolejnym pikselom. W ten sposób czytając taki plik np. za pomocą Inputbin można te słowa Word słać prosto do lcd pracującego w standardzie 5-6-5. Rozumiem, że składowe RGB oryginalnego pliku zostały przycięte czyli poprzesuwane w prawo o 3, 2 i 3 bity :-). Stosując dodatkowo poniższy prosty algorytm kompresji można dość znacząco zmniejszyć wynikowy ciąg danych. Przykład:

    Ciąg danych bez kompresji Skompresowany
    ================ ==========
    05 = 05
    05 05 = 05 05 00
    05 05 05 = 05 05 01
    05 05 05 05 = 05 05 02
    05 05 05 05 05 = 05 05 03
    05 05 05 05 05 05 = 05 05 04
    05 05 05 05 05 05 05 = 05 05 05
    05 05 05 05 05 05 05 05 = 05 05 06
    ...
    ...
    do 257 powtórzeń 05 = 05 05 FF

    Ale to już dodatkowa opcja, która delikatnie komplikuje procedurę przesyłania danych do LCD.
  • Poziom 43  
    No dane są przycięte (z 8-miu bitów jest brane 5 albo 6 najstarszych bitów).
    Inaczej tego się przecież nie dało zrobić.
    Kompresja fajna, ale jeszcze nigdy mi nie przyszło robić żadnej. Może spróbuję. Ale jak już to może jakąś bardziej klasyczną.
    Ale to nie teraz. Czasu mam mało.
  • Poziom 26  
    atom1477 napisał:
    Zapisuje dane WORD w formacie 565.


    Nie jestem pewien czy ta konstrukcja jest poprawna:
    Code:

    Data:=Data + ((Kolor Shr 2) And $0000001F) Shl 0;
    Data:=Data + ((Kolor Shr 10) And $0000003F) Shl 5;
    Data:=Data + ((Kolor Shr 18) And $0000001F) Shl 11;

    ... bo Kolor to jak rozumiem 24bity R( 8 )G( 8 )B( 8 ) a wynikowa zmienna Data powinna być R(5)G(6)B(5) więc to przesuwanie wydaje się "podejrzane", zwłaszcza w lewo o 0 przesunięć... mogę się jednak mylić...Wydaje się, że powinno przycinać się przycinać najmniej znaczące bity a nie najbardziej znaczące... robiw
  • Poziom 43  
    To jest tak napisane żeby było widać jak to działa. Kod jest na maxa nieoptymalnie napisany, ale właśnie po to żeby było widać jak to działa i żeby było łatwo wprowadzać zmiany.
    Przykład: to przesuwanie o 0.
    Był mały błąd (2 zamiast 3 i kolejne liczby tak samo) . Już poprawiłem.
    Ale reszta jest dobrze. Obcinane są właśnie najmniej zanczące bity.
  • Poziom 26  
    Witaj,
    Jeśli Zmienna DWord zawierająca kolor ma wzorzec:
    R7R6R5R4R3R2R1R0-G7G6G5G4G3G2G1G0-B7B6B5B4B3B2B1B0
    a zmienna wynikowa Data ma mieć wzorzec:
    R4R3R2R1R0-G5G4G3G2G1G0-B4B3B2B1B0

    to nada wydaje się, że zmienna koloru jest źle przesuwana. Choćby pierwsze równanie powinno być:

    Code:

    Data:=Data + ((Kolor Shr 5) And $F800) Shl 0;

    Czyli na samym początku przesuwamy Kolor o 5 miejsc w prawo a następnie maskujemy 11 najmłodszych bitów otrzymanej zmiennej by pozostawić wyłącznie R4...R0. Bity R7...R5 "wypadną" automatycznie bo nie zmieszczą się w zmiennej Data (Word). Kolejne kroki też do poprawki...robiw
  • Poziom 43  
    Kolor jest taki:
    B7B6B5B4B3B2B1B0-G7G6G5G4G3G2G1G0-R7R6R5R4R3R2R1R0

    Przesuwamy o 3:
    0_0_0_B7B6B5B4B3B2B1B0-G7G6G5G4G3G2G1G0-R7R6R5R4R3

    I mamy 5 bitów R:
    R7R6R5R4R3

    Przesuwamy o 0:
    00000 000000 RRRRR




    Przesuwamy o 10:
    0_0_0_0_0_0_0_0_0_0_B7B6B5B4B3B2B1B0-G7G6G5G4G3G2

    I mamy 6 bitów G:
    G7G6G5G4G3G2

    Przesuwamy o 5:
    00000 GGGGGG 00000





    Przesuwamy o 19:
    0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_B7B6B5B4B3

    I mamy 5 bitów B:
    B7B6B5B4B3
    Przesuwamy o 11:
    BBBBB 000000 00000

    Czyli jest Git.

    Dodano po 8 [minuty]:

    W ogóle to skąd wziąłeś tą wartość $F800?
  • Poziom 26  
    No OK. Tyle, że ja myślałem, iż wejściowy format to RGB a nie BGR i stąd pomyłka. wiem, że bitmapa ma BGR ale myślałem, że kontrolka w Delphi ma już normalnie ;-). Inna sprawa, że na wyjściu oczekiwałem RGB 5-6-5 a nie również BGR :-)... robiw
  • Poziom 43  
    Ale to i tak bez różnicy.
    R jest równe B (chodzi mi o to że 5 bitów) więc czy to RGB czy BGR to przesunięcia bitów i tak były by takie same.
  • Poziom 26  
    ...no nie wiem. Generalnie zmieniłem trochę równania by w efekcie otrzymać format wyjściowy R(5)G(6)B(5) czyli w kolejności RGB (oryginał ma GBR):

    Code:

    Data:=0;

    Data:=Data + (Kolor Shl 11);
    Data:=Data Or ((Kolor Shr 3) And $7E0);
    Data:=Data Or ((Kolor Shr 16) And $1F);


    Dodam jeszcze wspomnianą kompresję i zapis zwykłych danych binarnych (format wyjściowy BIN) i będzie cacy...robiw
  • Poziom 43  
    robiw napisał:
    ...no nie wiem.

    Ale ja wiem ;)
    Właśnie sprawdziłem i działa dobrze.

    robiw napisał:
    Dodam jeszcze wspomnianą kompresję i zapis zwykłych danych binarnych (format wyjściowy BIN) i będzie cacy...robiw

    To podziel się później efektami.
  • Poziom 26  
    OK. Dam znać. Tylko zainstaluję Delphi :-)... robiw
  • Poziom 43  
    No to jak? Nie kompilowałeś tego jeszcze? To jak doszedłeś do tego że coś jest źle?
  • Poziom 26  
    Normalnie ;-). Przecie shr, shl, and i or to podstawa :-). Wystarczy rozrysować ;-)... robiw