Bitmapy

0

Znalazłem w necie strukturę plików bmp, chcę zrobić program, który koduje tekst do bitmapy według algorytmu z tej strony. Czy w WinAPI jest gotowa struktura BMP? Próbowałem zrobić swoją, niektóre dane były prawidłowe, niektóre nie (Zapewne chodzi tu o systemy liczbowe)
Struktura:

#include <stdio.h>
#include <Windows.h>

int main()
{

    struct bitmapa
    {

        char indentifer[2];
        DWORD filesize;
        DWORD reserved;
        DWORD offsetdata;
        DWORD headersize;
        DWORD width;
        WORD height;
        WORD planes;
        WORD bitsperpixel;
        DWORD compression;
        DWORD datasize;
        DWORD hresolution;
        DWORD vresolution;
        DWORD colors;
        DWORD icolors;
        char palette[4];
        char bmpdata[2000000];


    };

    FILE* plik = fopen("lol.bmp","r");

    bitmapa obrazek;

    fread(&obrazek,1, sizeof( bitmapa ), plik);

    printf("%d", obrazek.bmpdata);


	return 0;
}

Jeżeli jest gotowa struktura, to podajcie :-) Jeżeli nie, to co jest źle w tej i jak korzystać z wczytanych danych (one są w systemie 16 chyba?).
Pozdrawiam.

0

Jest taka struktura.W dokumentacji API szukaj BitmapCoreHeader i BitmapInfoHeader ;)

0

Tak wygląda nagłowek bitmapy 256 kolorowej.

 { Paleta pliku *.BMP zapisanego w 256 kolorach                      }
 { Opis pol:                                                         }
 { B - skladowa niebieska                                            }
 { G - skladowa zielona                                              }
 { R - skladowa czerwona                                             }
 { Z - pole zarezerwowane                                            }
 { Nalezy pamietac, ze w pliku sexonixa skladowe B i R sa zamienione }
 { miejscami, a pole zarezerwowane nie wystepuje                     }
 PPalBMP = ^TPalBMP;
 TPalBMP = ARRAY [0..255] OF RECORD B, G, R, Z :byte; END;

 { Naglowek pliku *.BMP. W programie zastosowany do kontroli formatu  }
 { zdjec poddawanych obrobce. W nawiasach podano offset pola wzgledem }
 { poczatku pliku                                                     }
 THeader = RECORD
           { typ - Specyfikator typu pliku okreslajacy typ                 }
           { przechowywanego obrazu                                        }
           { BM - BitMapa                                                  }
           { BA - Bitmap Array (tablica bitmapy                            }
           { CI - Color Icon (kolorowa ikona)                              }
           { CP - Color Pionter (kursor myszy)                             }
           { IC - Icon (ikona)                                             }
           { PT - Pointer (kursor myszy)                                   }
   { 00h } typ         :ARRAY [0..1] OF char;
           { FSIze - Rozmiar calego pliku podany w bajtach. Nas            }
           { interesuje tylko rozmiar 65078                                }
   { 02h } FSize       :LongInt;
           { wolne1 i wolne2 - Pola zarezerwowane, zawsze 0                }
   { 06h } wolne1      :word;
   { 08h } wolne2      :word;
           { offset - Odleglosc od poczatku pliku pierwszego bajtu         }
           { obrazu, podana w pikselach                                    }
   { 0Ah } offset      :LongInt;
           { info - Rozmiar naglowka informacyjnego bitmapy podany         }
           { w bajtach. Dla bitmap tworzonych w roznych systemach          }
           { moze przybierac rozna wartosc:                                }
           { 12 - dla systemu OS/2 1.x,                                    }
           { 40 - dla systemu Windows 3.x,                                 }
           { 64 - dla systemu OS/2 2.x                                     }
   { 0Eh } info        :LongInt;
           { szer - Szerokosc obrazu podana w pikselach. Dla programu      }
           { musi byc rowna 320                                            }
   { 12h } szer        :LongInt;
           { wys - Wysokosc obrazu podana w pikselach. Dla programu        }
           { musi byc 200 }
   { 16h } wys         :LongInt;
           { plany - liczba planow w obrazie, zawsze 1. Inne wartosci      }
           { mozna spotkac w animowanych gifach                            }
   { 1Ah } plany       :word;
           { BitPerPixel - Liczba bitow uzywana do reprezentacji           }
           { jednego piksela: }
           {  1 - bitmapa monochromatyczna (czarno - biala),               }
           {  4 - bitmapa 16-kolorowa,                                     }
           {  8 - bitmapa 256-kolorowa,                                    }
           { 24 - bitmapa sklada sie z pikseli mogacych przybierac jeden   }
           {      z 16777216 kolorow, plik bitmapy nie ma palety kolorow,  }
           {      kazde kolejne trzy bajty obrazu oznaczaja intenywnosc    }
           {      barwy czerwonej, zielonej i niebieskej dla kolejnych     }
           {      pikseli }
   { 1Ch } BitPerPixel :word;
           { kompresja - Typ kompresji obrazu:                             }
           { 0 - BI_RGB, obraz nieskompresowany,                           }
           { 1 - BI_RLE, 8 bitowa kompresja RLE,                           }
           { 2 - BI_RLE, 4 bitowa kompresja RLE                            }
   { 1Eh } kompresja   :LongInt;
           { rozmiar - Rozmiar obrazu podany w bajtach                     }
   { 22h } rozmiar     :LongInt;
           { HDPI Horizontal Dots Per Inch - Pozioma rozdzielczosc obrazu  }
           { podana w ilosci punktow na cal kwadratowy                     }
   { 26h } HDPI        :LongInt;
           { VDPI Vetical Dots Per Inch - Pionowa rozdzielczosc obrazu     }
           { podana w ilosci punktow na cal kwadratowy                     }
   { 2Ah } VDPI        :LongInt;
           { kolory - Jezeli liczba uzywanych kolorow wynosi zero, bitmapa }
           {uzywa liczby kolorow zgodnej z liczba bitow uzywanych do       }
           { reprezenatcji jednego piksela; jezeli pole zawiera wartosc    }
           { niezerowa, okresla ona liczbe wzorcow koloru uzywanych do     }
           { wyswietlania obrazu }
   { 2Eh } kolory      :LongInt;
           { znaczace - Liczba wzorcow koloru brana pod uwage podczas      }
           { ustalania kolorow pikseli; jezeli to pole zawiera 0, to       }
           { znaczy, ze wszystkie kolory sa uzywane                        }
   { 32h } znaczace    :LongInt;
 END;

CONST
 SizePalBMP  = 1024;   { rozmiar palety bitmapy 8 bitowej }
 SizePalSEX  = 768;    { rozmiar palety pliku sexonixa    }
 HeaderSize  = 54;     { rozmiar naglowka informacyjnego  }

Bitmapa 24bitowa różni się tym, że nie posiada palety kolorów. Ma nagłówek i dane obrazu. Każdy piksel jest zapisany jako RGB.

 
 Dane :array [0..Szerokosc, 0..Wysokosc] of record r,g,b :Byte; end;

(mniej więcej)

0

Szukałem o BitmapCoreHeader i tym drugim. Tylko teraz mam problem. Ładować do tych struktur w sposób jaki mam w kodzie? Binarnie, czy nie? I tak, BitmapInfoHeader zawiera cały nagłówek z informacjami o pliku, czyli ilość puntków, szerokość, ile bajtów na jeden px itd. A gdzie odczytam poszczególne pixele? Nie widzę tego w tych strukturach :>

0

Olek, wiem jak wygląda nagłówek. Ta struktura, którą napisałęm obsługuje go. To co podałeś tyczy się Delphi, ja potrzebuje C++ i WinAPI. I teraz tak, problem z nagłówkiem mały, gorzej z wczytywaniem danych o każdym punkcie do struktury. Z tym mam problem.

0

Fragment kodu w WinApi do czytania pliku.

HPALETTE hPal;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
LBITMAPINFO lpbi = 0;
HFILE hFile;
DWORD nClrUsed, nSize;
HDC hDC;
HBITMAP hBitmap;
void *bits;
do {
  if ((hFile = _lopen(data.FileName, OF_READ)) == HFILE_ERROR) break;
  if (_hread(hFile, &bfh, sizeof(bfh)) != sizeof(bfh)) break;
  if (bfh.bfType != 'BM') break;
  if (_hread(hFile, &bih, sizeof(bih)) != sizeof(bih)) break;
  nClrUsed = (bih.biClrUsed) ? bih.biClrUsed : 1 << bih.biBitCount;
  nSize = sizeof(BITMAPINFOHEADER) + nClrUsed * sizeof(RGBQUAD);
  lpbi = (LPBITMAPINFO) GlobalAllocPtr(GHND, nSize);
  if (!lpbi) break;
  MoveMemory(lpbi, &bih, sizeof(bih));
  nSize = nClrUsed * sizeof(RGBQUAD);
  if (_hread(hFile, &lpbi->bmiColors, nSize) != nSize) break;
  if (_llseek(hFile, bfh.bfOffBits, 0) == HFILE_ERROR) break;
  nSize = bfh.bfSize-bfh.bfOffBits;
  if ((bits = GlobalAllocPtr(GHND, nSize)) == NULL) break;
  if (_hread(hFile, bits, nSize) != nSize) break;
  hDC = GetDC(hWnd);
0

Ah sorka,zapomniałem o jeszcze jednej ważnej strukturze-BitmapFileHeader.W jednym z jej pól jest właśnie zawarta informacja o odległości od początku pliku do bajtów pixeli bitmapy.No teraz to już chyba pójdzie Ci z górki Bracie ;

cały ów plik bitmapy wygląda tak:
BitmapFileHeader
BitmapInfoHeader albo inny
Bity bitmapy

0

Oby. na razie chwila relaxu w PingPonga i wracam do analizowania tego co tu napisaliście :-)
Dzięki bardzo! ;-)

0

Hmm, Adamie, ten kod jest chyba walnięty. Można wiedzięć skąd go masz?

0

Sorry, że trzeci post, w SPACJA końcu muszę się zarejestrować. A czy mogę wczytać bitmapę funkcją LoadBitmap? Albo LoadImage? Czy wtedy też będę miał taką możliwość obróbki?
I czy ktoś może wyjaśnić mi działanie kodu od Pana Adama, bo on jest strasznie wyrwany z kontekstu, breakuje w nim zmiennych i w ogóle mało łapie w nim.
Pozdrawiam. [glowa]

0

Wydarłem go kiedyś kompilatorowi z bibliotek. Nie pamiętam dokładnie jakich. Ale wracając do problemu. Nieważne jakie masz zdjęcię to ma ono nagłowek informacyjny, który z kolei ma ustalony rozmiar. Czyli rozmiar danych = rozmiar pliku - nagłowek (i inne bzdury).

0

Z tego co pamiętam nie możesz użyć tych funkcji.W dokumentacji poczytaj o arcyważnyej różnicy między bitmapami zależnymi od urządzenia (Device Dependent Bitmap,DDB) a bitmapami niezależnymi od urządzenia (Device Independent Bitmap,DIB).Skoro operujesz na pliku .bmp,to jest to DIB,i musisz funcje operujące na takim rodzaju bitmap wykorzystywać.ALe odnośnie wczytywania,powinno zadziałać coś takiego:
1.operatorem np new przydziel blok pamięci o wielkości sizeof(plik.bmp)
2.użyj zwykłej funkcji wczytującej binarnie dane z pliku,aby załadować plik do pamięci
3.zwiąż wskaźnik na strukturę BITMAPFILEHEADER z początkiem bufora
4.zwiąż wskaźnik na strukturę BITMAPINFOHEADER z początkiem bufora+sizeof(BITMAPFILEHEADER)
5.jak ci to potrzeba-możesz sobie ustawić wskaźnik do pixeli poprzez adres_bufora+pole_odległości_do_pixeli z BITMAPFILEHEADER

w dokumentacji API masz strzałkę odnośnik,rozwijającą ci odpowiednią gałąź tematyczną-przestudiuj to uważnie Bracie,i powodzenia xD

0

No to jeszcze Cię Bracie pomęcze ;p Nie rozumiem dwóch rzeczy, mianowicie jakiego typu pamięć mam zaalokować i co to znaczy zawiązać wskaźnik ?!?! Pozdrawiam.

0

hmmm a jak powiem ustawić wskaźnik będzie bardziej zrozumiale?;P

oka,ja wczytuję bitmapę tak (w dokumentacji poszukaj Bracie dokładnego znaczenia poszczególnych funkcji):

HANDLE UchwytPliku;
static BITMAPFILEHEADER *pbmfh;
static BITMAPINFO *pbmi;
BYTE *pBits;
DWORD RozmiarPliku,BajtyWczytane;

RozmiarPliku=GetFileSize(uchwytPliku,NULL);
pbmfh=(BITMAPFILEHEADER*)malloc(RozmiarPliku);
ReadFile(UchwytPliku,pbmfh,RozmiarPliku,&BajtyWczytane,NULL);
pbmi=(BITMAPINFO*)(pbmfh+1);//ustawienie wskaźnika na strukturę BITMAPINFOHEADER
pBits=(BYTE*)pbmfh+pbmfh->bfOffBits;//a tu masz ustawienie wskaźnika na pixele ;P

w razie dalszych kłopotów,to polecam Bracie skołować sobie "Programowanie Windows" Charlesa Petzola-bitmapy są skomplikowanym tematem,a tam jest to ujęte całkiem dobrze(stamtąd wziąłem informacje podczas pisania mojego programu)

1 użytkowników online, w tym zalogowanych: 0, gości: 1