2011-12-29 4 views
2

J'ai un problème! Je voudrais obtenir les informations RVB de chaque pixel en bitmap 24 bits. Jusqu'à présent, j'ai écrit un code qui obtient une information sur bitmap, mais j'ai un problème avec les informations de gettin RVB sur chaque pixel. Je voudrais garder cette information dans les tabel pixs des structures Pixel. Pourriez-vous m'aider avec ça?Comment lire pixel après pixel en bmp

Je mets mon code ci-dessous:

 #include <iostream> 
#include <fstream> 
#include <conio.h> 

using namespace std; 

#pragma pack(2) 

struct BITMAPFILEHEADER    // File header 
{ 
    char bfType[2];     // File type: should be BM (0x42 0x4D) 
    int bfSize;      // File size in bytes 
    short bfReserved1;    // Reserved - for what i have no idea :P 
    short bfReserved2;    // -||- 
    int bfOffBits;     // Offset, adress of the beginning of the information about image (pixels) 
}; 

struct BITMAPINFOHEADER    // Bitmap header 
{ 
    unsigned int biSize;    // Size of this header 
    unsigned int biWidth;    // Width of image (in pixels) 
    unsigned int biHeight;   // Height of this image (in pixels) 
    unsigned short biPlanes;   // Numer of color planes, always 1 
    unsigned short biBitCount;  // Number of bytes for pixel. Possibility values :1,4,8,16, 24 and 32 
    unsigned int biCompression;  // Used compression (0 -none) 
    unsigned int biSizeImage;   // Size of image 
    signed int biXPelsPerMeter;  // Horizontal resolution of the image (pixel per meter) 
    signed int biYPelsPerMeter;  // Vertical resolution of the image (pixel per meter) 
    unsigned int biClrUsed;   // Number of colors in the color palette, or 0 to default to 2^n (0- no palette) 
    unsigned int biClrImportant;  // Number of important colors used 
}; 



#pragma pack(push, 1) 

struct Pixel{ 
    unsigned int blue; // or double? 
    unsigned int green; 
    unsigned int red; 
    //unsigned char reserved; 
}; 
#pragma pack(pop) 

int main(){ 

    // Openning the file 

    cout << "Openning the file for reading: "<< endl; 
    _getch(); 
    ifstream ifs("moj.bmp", ios::binary); 

    if(!ifs){ 
     cout << " There is no such of file "; 
     _getch(); 
     return 0; 
    } 

    // Reading information about BITMAPFILEHEADER 
    char* temp = new char[sizeof(BITMAPFILEHEADER)]; 
    ifs.read(temp, sizeof(BITMAPFILEHEADER)); 
    BITMAPFILEHEADER* bfh = (BITMAPFILEHEADER*)(temp); 

    cout << "\n FILHEADER\n"; 
    cout << "\n File type: " << bfh->bfType[0] << bfh->bfType[1] << endl; 
    cout << " File size: " << bfh->bfSize << endl; 
    cout << " Offset(adress of beggining of the image information): " << bfh->bfOffBits << endl; 
    _getch(); 


    // Reading information about BITMAPINFOHEADER 
    temp = new char[sizeof(BITMAPINFOHEADER)]; 
    ifs.read(temp, sizeof(BITMAPINFOHEADER)); 
    BITMAPINFOHEADER* bih = (BITMAPINFOHEADER*)(temp); 

    cout << "\n INFOHEADER\n"; 
    cout << "\n Header size: " << bih->biSize << endl; 
    cout << " Image width: " << bih->biWidth << endl; 
    cout << " Image height: " << bih->biHeight << endl; 
    cout << " Number of bytes for pixel: " << bih->biBitCount << endl; 
    cout << " Used compression: " << bih->biCompression << endl; 
    cout << " Image size: " << bih->biSizeImage<< endl; 
    cout << " Horizontal resolution: " << bih->biXPelsPerMeter << endl; 
    cout << " Vertical resolution: " << bih->biYPelsPerMeter << endl; 
    cout << " Number of colors in the color palette: " << bih->biClrUsed << endl; 
    cout << " Number of important colors used: " << bih->biClrImportant << endl; 
    _getch(); 

    Pixel** pixs = new Pixel*[bih->biHeight]; 
    for (int i = 0; i < bih->biHeight ; ++i) 
     pixs[i] = new Pixel[bih->biWidth]; 


    ifs.seekg(bfh->bfOffBits, ios::beg); // bfOffBits points for beginning of the image information 


       /* I have no idea how to read pixel after pixel in this moment */ 


    _getch(); 

    for (int i = 0; i < bih->biHeight; ++i) 
     delete pixs[i]; 

    delete pixs; 
    delete bfh; 
    delete bih; 

    return 0; 

} 

Cela fonctionne, mais comment dois-je changer cela sur une variable entière? Par exemple:

pixs[i][j]=(unsigned int)r; 

ne fonctionne pas. Après cette commande en pixs [i] [j] il y a de la corbeille ...:/

Peut-être un conseil?

+0

Si vous n'avez pas besoin de plus de 8 bits par pixel, 'unsigned char' (ou' uint8_t') devrait suffire. –

+0

Oui, je le sais maintenant, il devrait y avoir un caractère non signé. Mais j'ai toujours un gros problème en un instant je veux dire au moment où je lis le pixel, car la fonction de lecture comme premier argument nécessite * char et je n'ai aucune idée de comment faire cela pour que cela fonctionne ...:/ – user1120709

Répondre

0

Lorsque vous avez compensé et taille de l'image et vous êtes sûr que l'image est 24bit (1 byte pour chaque couleur), ca vous numérisez votre pixel tampon d'image après pixel.

uint8_t* pixelTmp = new uint8_t[3]; 
for (int i = 0; i != imageSize; ++i) { 
    ifs.read(pixelTmp, 3); 
    pixelTmp[0]; /* is blue 0-255 */ 
    pixelTmp[1]; /* is green 0-255 */ 
    pixelTmp[2]; /* is red 0-255 */ 
} 

valeur Assign de pixelTmp[0] à votre propre pixel bleu et ainsi de suite ...

+0

Mais les gars ... avez-vous vérifié comment ifs.read() fonctionne. Le premier argument de cette fonction est char, c'est pourquoi j'ai un gros problème. Donc: int r, g, b; ifs.read (&b, 1); ifs.read (&g, 1); ifs.read (&r, 1); ne fonctionne pas, aussi uint8_t pixelTmp = new uint8_t [3]; pour (int i = 0; i! = imageSize; ++ i) {ifs.read (pixelTmp, 3); pixelTmp [0 ];/* est bleu 0-255/pixelTmp [1];/est vert 0-255/pixelTmp [2];/est rouge 0-255 * /} – user1120709

0

Comme vous pouvez le voir here, 1 pixel utilise 3 octets. Cela signifie que le premier octet est bleu, le second vert et le troisième est rouge. Ce que vous devez faire maintenant, est une boucle à travers le reste du fichier bitmap, la lecture 3 octets séparés, et de les stocker dans votre struct:

char r, g, b; 
ifs.read(&b, 1); 
ifs.read(&g, 1); 
ifs.read(&r, 1); 

Vous pouvez vérifier par exemple 1 pour voir comment les lignes de l'image sont stockées .

+0

Joahim, merci pour la correction, mais je sais déjà que biBitCount est le nombre de bits pour les pixels ... C'était une faute de frappe ...: P Quoi qu'il en soit ... wow ... merci les gars pour votre aide Vraiment, maintenant je vais juste tester ça, et vous dire comment ça s'est passé :) – user1120709

+0

Mais les gars ... avez-vous vérifié le fonctionnement de ifs.read() Le premier argument de cette fonction est * char, c'est pourquoi j'ai un gros problème, donc: int r, g, b; ifs.read (&b, 1); ifs.read (&g, 1); ifs.read (&r, 1); ne fonctionne pas, aussi uint8_t * pixelTmp = new uint8_t [3]; pour (int i = 0; i! = ImageSize; ++ i) {ifs.read (pixelTmp, 3); pixelTmp [0 ];/* est bleu 0- 255 */pixelTmp [1];/* est vert 0-255 */pixelTmp [2];/* est rouge 0-255 * /} – user1120709

+0

Le premier argument est char *, un pointeur vers un tampon. Depuis que vous avez lu un chararcter, vous pouvez simplement choisir le pointeur vers les variables. Je pensais à la fonction fgetc, c'est pourquoi j'ai choisi ints au lieu de caractères. J'ai corrigé ma réponse maintenant. –

0

D'abord, le champ biBitCount du BITMAPINFOHEADER est pas le nombre d'octets par pixel, il est le nombre de bits de .

Il s'agit du nombre de bits que vous devez lire dans les données brutes pour obtenir un pixel. Pour les pixels de 24 bits, il suffit de lire comme suggéré dans les réponses d'Alessandro Pezzato ou de Ben. Les pixels de 32 bits contiennent un octet supplémentaire qui contient normalement un canal alpha (à quel point le pixel est transparent). Il existe plusieurs formats 16 bits différents et le format 8 bits est généralement un index dans une table de couleurs. Je ne connais pas les formats 4 bits, mais 1 bit est en noir et blanc pur (0 est noir et 1 est blanc.)

Pour les formats 8, 16, 24 et 32 ​​bits, lisez-en un à quatre octets et convertir en fonction du format de couleur. Pour les valeurs inférieures à 8 (4 et 1), lisez un octet à la fois, puis utilisez le masquage dans une boucle pour obtenir les bits et stockez-les dans votre format interne. Pourquoi votre couleur de pixel est de type «int»?

Questions connexes