Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Problem z wcztaniem Bitmapy

Ostatnio zmodyfikowano 2009-11-29 13:22
Autor Wiadomość
ZuuM
Temat założony przez niniejszego użytkownika
Problem z wcztaniem Bitmapy
» 2009-11-28 20:17:47
Witam. Stworzyłem sobie strukturę w której chciałbym przechowywać bitmapy. Nie wiem jak się zabrać do odczytania pojedynczego pixla z pliku do mojej struktury. Prosiłbym o jakieś wskazówki. Z góry dziękuję.
Oto treść klasy:
C/C++
class Kolor {
private:
    int r;
    int g;
    int b;
public:
    Kolor() {
        r = 0;
        b = 0;
        g = 0;
    }
    Kolor( int red, int blue, int green ) {
        r = red;
        b = blue;
        g = green;
    }
    void UstawKolor( int red, int blue, int green ) {
        r = red;
        b = blue;
        g = green;
    }
    void PobierzKolor( int * red, int * blue, int * green ) {
        * red = r;
        * blue = b;
        * green = g;
    }
};
class Mapa {
private:
    Kolor ** mapa;
    unsigned int szerokosc;
    unsigned int wysokosc;
    unsigned int sizepixel;
protected:
    int tr, tb, tg;
public:
    Mapa( unsigned int szer, unsigned int wys, unsigned int size ) {
        szerokosc =( szer / size ) * size;
        wysokosc =( wys / size ) * size;
        sizepixel = size;
        tr = 0;
        tb = 0;
        tg = 0;
        mapa = new Kolor *[ wysokosc ];
        for( int i = 0; i < wysokosc; i++ ) {
            mapa[ i ] = new Kolor[ szerokosc ];
        }
    }
    void RysujMape() {
        int r, b, g;
        for( int j = 0; j < wysokosc; j++ )
        for( int i = 0; i < szerokosc; i++ ) {
            mapa[ i ][ j ].PobierzKolor( & r, & b, & g );
            glBegin( GL_POINTS );
            glColor3f( r / 255.0f, b / 255.0f, g / 255.0f );
            glVertex2f(( - 1.0f +( 1.0 * i /( szerokosc / 2.0f ) ) ),( - 1.0f +( 1.0 * j /( wysokosc / 2.0f ) ) ) );
            glEnd();
        }
    }
    AUX_RGBImageRec * LoadBMP( char * Filename )
    {
        FILE * File = NULL;
        if( !Filename )
        {
            return NULL;
        }
        File = fopen( Filename, "r" );
        if( File )
        {
            fclose( File );
            return auxDIBImageLoad( Filename );
        }
        return NULL;
    }
   
    int LoadGLTextures( char * filename )
    {
        int Status = FALSE;
        AUX_RGBImageRec * TextureImage[ 1 ];
        memset( TextureImage, 0, sizeof( void * ) * 1 );
       
       
        if( TextureImage[ 0 ] = LoadBMP( filename ) ) {
        }
        if( TextureImage[ 0 ] )
        {
            if( TextureImage[ 0 ]->data )
            {
                free( TextureImage[ 0 ]->data );
            }
            free( TextureImage[ 0 ] );
        }
        return Status;
    }
};
P-11873
DejaVu
» 2009-11-28 21:50:01
Jeśli odczytałeś bitmapę z pliku do pamięci to zapewne w pamięci masz jej reprezentację w postaci RGBA.
C/C++
int kolor = 0xffeeddcc;
int r = kolor % 256;
kolor /= 256;
int g = kolor % 256;
kolor /= 256;
int b = kolor % 256;
kolor /= 256;
int a = kolor % 256;
Kolejność strzelałem, być może powinieneś wczytywać w odwrotnej kolejności, tj. abgr (choć wątpię).
P-11877
ZuuM
Temat założony przez niniejszego użytkownika
» 2009-11-29 08:07:09
Czyli na to wyglądać tak? Wkleje fragment kodu:
C/C++
if( TextureImage[ 0 ] = LoadBMP( filename ) ) {
    void * koloradres = TextureImage[ 0 ]->data; //to jest wskaznik na dane odczytane z obrazka
   
    for( int i = 0; i < TextureImage[ 0 ]->sizeY; i++ ) {
        for( int j = 0; j < TextureImage[ 0 ]->sizeX; j++ ) {
            int color =( int ) *( koloradres );
            int r =( int )( color ) / 256;
            color =( color ) / 256;
            int g =( int )( color ) / 256;
            color =( color ) / 256;
            int b =( int )( color ) / 256;
            mapa[ i ][ j ].UstawKolor( r, g, b );
            koloradres++; // tutaj musze przesunąć adres do następnego pixla koloru
        }
    }
}

Tylko teraz nie wiem jak przejsc do następnego koloru ??? koloradress++??
Wyswietlają mi się dwa błedy jeden w lini int color= (int) *(koloradres); 
Zaś drugi w koloradres++;
P-11886
ZuuM
Temat założony przez niniejszego użytkownika
» 2009-11-29 11:14:00
Trochę to zmieniłem i zaczęło mi coś wyświetlać podobnego do mojej bitmapy. Jest to fragment prawego dolnego rogu bitmapy (to nie jest nawet  1/4 może raczej 1/16 tej bitmapy). Wyświetla mi go w skali Niebieskiego koloru. Tak jak w skali szarości tylko że na niebiesko. TextureImage[0]->data to ze specyfikacji jest wskaźnikiem na unsigned char, czyli pod tym wskaźnikiem będzie siedziała 8 bitowa wartosc.
1. Czy może tam być 32bitowa?? RGBA?
2. Jeżeli w programie Paint zapisuje to w formacie 24bitowym kanał alpfa będzie uwzględniony?

C/C++
if( TextureImage[ 0 ] = LoadBMP( filename ) ) {
    unsigned char * koloradres = TextureImage[ 0 ]->data; //to jest wskaznik na dane odczytane z obrazka
   
    for( int i = 0; i < TextureImage[ 0 ]->sizeY; i++ ) {
        for( int j = 0; j < TextureImage[ 0 ]->sizeX; j++ ) {
            int color =( int ) *( koloradres );
            int r =( int )( color ) % 256;
            color =( color ) / 256;
            int g =( int )( color ) % 256;
            color =( color ) / 256;
            int b =( int )( color ) % 256;
            mapa[ j ][ i ].UstawKolor( b, g, r );
            koloradres++; // tutaj musze przesunąć adres do następnego pixla koloru
        }
    }
}
P-11891
DejaVu
» 2009-11-29 13:00:01
Powiem tak: jeśli używasz jakiejś biblioteki dzięki której możesz wczytywać bitmapy to zapewne istnieje jakaś funkcja do pobierania składowych RGB. W allegro na pewno jest taka funkcja. W zależności od ilości ustawionych kolorów (8bit/16bit/24bit/32bit) musisz mieć napisaną funkcję inaczej. Funkcje dostarczone z biblioteką są na to odporne i zawsze zwracają poprawną wartość składowych (przynajmniej tak powinno być w teorii).
P-11895
ZuuM
Temat założony przez niniejszego użytkownika
» 2009-11-29 13:22:53
Jupi udało mi się :D. Już wczytuje i wyświetla dobrze bitmape. Zmieniłem nieco tamtą funkcję TextureImage[0]->data to wskaźnik, a jak wskaźnik do początku tablicy RGB w pętli wyliczam pozycje pixla i kolejno odczytuje r, g, b:
Zamieszczę cały kod programu. Może komuś się kiedyś do czegoś to przyda. Pozdrawiam i dziękuję za podpowiedzi.
C/C++
/*Autor: Maciej Sawoń
* www.ddt.pl - portal internetowy poświęcony Grafice Komputerowej, z której czerpałem niektóre rozwiązania
**************************/

#include <GL\gl.h>
#include <GL\glaux.h>
#include <GL\openglut.h>
#include <GL\glext.h>

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>


#define WSP_X 520
#define WSP_Y 520
#define SIZEP 1




/**************************
* Function Declarations
*
**************************/
class Kolor {
private:
    int r;
    int g;
    int b;
public:
    Kolor() {
        r = 0;
        b = 0;
        g = 0;
    }
    Kolor( int red, int blue, int green ) {
        r = red;
        b = blue;
        g = green;
    }
    void UstawKolor( int red, int blue, int green ) {
        r = red;
        b = blue;
        g = green;
    }
    void PobierzKolor( int * red, int * blue, int * green ) {
        * red = r;
        * blue = b;
        * green = g;
    }
};
class Mapa {
private:
    Kolor ** mapa;
    unsigned int szerokosc;
    unsigned int wysokosc;
    unsigned int sizepixel;
protected:
    int tr, tb, tg;
public:
    Mapa() {
        szerokosc = 640;
        wysokosc = 480;
        sizepixel = 1;
        tr = 0;
        tb = 0;
        tg = 0;
        mapa = new Kolor *[ wysokosc ];
        for( int i = 0; i < wysokosc; i++ ) {
            mapa[ i ] = new Kolor[ szerokosc ];
        }
    }
    Mapa( unsigned int szer, unsigned int wys ) {
        szerokosc = szer;
        wysokosc = wys;
        sizepixel = 1;
        tr = 0;
        tb = 0;
        tg = 0;
        mapa = new Kolor *[ wysokosc ];
        for( int i = 0; i < wysokosc; i++ ) {
            mapa[ i ] = new Kolor[ szerokosc ];
        }
    }
    Mapa( unsigned int szer, unsigned int wys, unsigned int size ) {
        szerokosc =( szer / size ) * size;
        wysokosc =( wys / size ) * size;
        sizepixel = size;
        tr = 0;
        tb = 0;
        tg = 0;
        mapa = new Kolor *[ wysokosc ];
        for( int i = 0; i < wysokosc; i++ ) {
            mapa[ i ] = new Kolor[ szerokosc ];
        }
    }
    void PobierzPixel( int x, int y, int * red, int * blue, int * green ) {
        mapa[ x ][ y ].PobierzKolor( red, blue, green );
    }
    void RysujPixel( int x, int y, int r, int g, int b ) {
        if( sizepixel == 1 ) {
            mapa[ x ][ y ].UstawKolor( r, b, g );
        } else {
            int cx, cy;
            cx = x / sizepixel;
            cy = y / sizepixel;
            for( int i = cx * sizepixel; i < cx * sizepixel + sizepixel; i++ ) {
                for( int j = cy * sizepixel; j < cy * sizepixel + sizepixel; j++ ) {
                    mapa[ i ][ j ].UstawKolor( r, b, g );
                }
            }
        }
    }
    void WyczyscMape() {
        int r;
        int b;
        int g;
        for( int i = 0; i < wysokosc; i++ )
             for( int j = 0; j < szerokosc; j++ ) mapa[ i ][ j ].UstawKolor( 0, 0, 0 );
       
    }
   
    void RysujLinie( int px1, int py1, int px2, int py2, int r, int b, int g ) {
       
        if( abs( px1 - px2 ) >= abs( py1 - py2 ) ) {
            int x = px1;
            float y = py1;
           
            for( int i = px1; i <= px2; i++ ) {
                x = i;
                this->RysujPixel( x,( int ) round( y ), r, b, g );
                y = y + 1.0 *( py2 - py1 ) /( px2 - px1 );
            }
        } else {
            float x = px1;
            int y = py1;
           
            for( int i = py1; i <= py2; i++ ) {
                y = i;
                this->RysujPixel(( int ) round( x ), y, r, b, g );
                x = x + 1.0 *( px2 - px1 ) /( py2 - py1 );
            }
        }
    }
    void FloodFill( int x, int y, int fr, int fb, int fg, int er, int eb, int eg ) {
        int r, b, g;
        if(( x >= 0 ) &&( x < WSP_X ) &&( y >= 0 ) &&( y < WSP_Y ) ) {
            this->PobierzPixel( x, y, & r, & b, & g );
           
            if((( r != fr ) ||( b != fb ) ||( g != fg ) ) &&(( r != er ) ||( b != eb ) ||( g != eg ) ) ) {
                this->RysujPixel( x, y, fr, fb, fg );
                this->FloodFill( x + sizepixel, y, fr, fb, fg, er, eb, eg );
                this->FloodFill( x - sizepixel, y, fr, fb, fg, er, eb, eg );
                this->FloodFill( x, y - sizepixel, fr, fb, fg, er, eb, eg );
                this->FloodFill( x, y + sizepixel, fr, fb, fg, er, eb, eg );
            }
        }
    }
    void RysujMape() {
        int r, b, g;
        for( int j = 0; j < wysokosc; j++ )
        for( int i = 0; i < szerokosc; i++ ) {
            mapa[ i ][ j ].PobierzKolor( & r, & b, & g );
            glBegin( GL_POINTS );
            glColor3f( r / 255.0f, b / 255.0f, g / 255.0f );
            glVertex2f(( - 1.0f +( 1.0 * i /( szerokosc / 2.0f ) ) ),( - 1.0f +( 1.0 * j /( wysokosc / 2.0f ) ) ) );
            glEnd();
        }
    }
    AUX_RGBImageRec * LoadBMP( char * Filename ) // Loads A Bitmap Image
    {
        FILE * File = NULL; // File Handle
        if( !Filename ) // Make Sure A Filename Was Given
        {
            return NULL; // If Not Return NULL
        }
        File = fopen( Filename, "r" ); // Check To See If The File Exists
        if( File ) // Does The File Exist?
        {
            fclose( File ); // Close The Handle
            return auxDIBImageLoad( Filename ); // Load The Bitmap And Return A Pointer
        }
        return NULL; // If Load Failed Return NULL
    }
    void PrzezucMape( int x, int y, unsigned char * dane ) {
       
        int pozycja, r, b, g;
        for( int i = 0; i < x; i++ ) {
            for( int j = 0; j < y; j++ ) {
                pozycja = i * 3 + j * x * 3;
                r = dane[ pozycja ];
                g = dane[ pozycja + 1 ];
                b = dane[ pozycja + 2 ];
                mapa[ i ][ j ].UstawKolor( r, g, b );
            }
        }
    }
    int LoadGLTextures( char * filename ) // Load Bitmaps And Convert To Textures
    {
        int Status = FALSE; // Status Indicator
        AUX_RGBImageRec * TextureImage[ 1 ]; // Create Storage Space For The Texture
        memset( TextureImage, 0, sizeof( void * ) * 1 ); // Set The Pointer To NULL
       
        if( TextureImage[ 0 ] = LoadBMP( filename ) ) {
            this->PrzezucMape( TextureImage[ 0 ]->sizeX, TextureImage[ 0 ]->sizeY, TextureImage[ 0 ]->data );
        }
        if( TextureImage[ 0 ] ) // If Texture Exists
        {
            if( TextureImage[ 0 ]->data ) // If Texture Image Exists
            {
                free( TextureImage[ 0 ]->data ); // Free The Texture Image Memory
            }
            free( TextureImage[ 0 ] ); // Free The Image Structure
        }
        return Status; // Return The Status
    }
};

Mapa * plansza = new Mapa( WSP_X, WSP_Y, SIZEP );
GLuint textura[ 1 ];


enum
{
    EXIT // wyjście
};

void Display()
{
    glClearColor( 0.0, 0.0, 0.0, 0.0 );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Clear The Screen And The Depth Buffer
    glLoadIdentity(); // Reset The View
    //plansza->FloodFill(200,10,255,0,0,255,255,255);
    //plansza->RysujMape();
    plansza->LoadGLTextures( "trawa.bmp" );
    plansza->RysujMape();
    glFlush();
    glutSwapBuffers();
}

void Menu( int value )
{
    switch( value )
    {
        // wyjście
    case EXIT:
        exit( 0 );
    }
}

int main( int argc, char * argv[] )
{
    glutInit( & argc, argv );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );
    glutInitWindowSize( WSP_X, WSP_Y );
   
    #ifdef WIN32
    glutCreateWindow( "Załaduj Mape" );
    #else
    glutCreateWindow( "Załaduj Mape" );
    #endif
   
    glutDisplayFunc( Display );
   
    // menu główne
    glutCreateMenu( Menu );
    #ifdef WIN32
    glutAddMenuEntry( "Wyjście", EXIT );
    #else
    glutAddMenuEntry( "Wyjscie", EXIT );
    #endif
    glutAttachMenu( GLUT_RIGHT_BUTTON );
    glutMainLoop();
    return 0;
}
P-11897
« 1 »
  Strona 1 z 1