Répondre à la discussion
Affichage des résultats 1 à 22 sur 22

enregistrement fichier bmp dans tableau, puis restitution



  1. #1
    olver62

    enregistrement fichier bmp dans tableau, puis restitution


    ------

    bonjour, j'ai quelques bases de C et je désirerrais concevoir un petit programme qui stocke les valeurs des pixels dans un tableau deux dimention (le bmp est monochrome donc 1 bit par pixel).
    j'ai trouvé divers fonctions permettant d'ouvrir un fichier en binaire, de me positionner à l'interieur et de lire des octets. j'ai ensuite décomposé les octets lus en bit pour les rentrer dans un tableau.

    lors de la restution (pour tester si le tableau est bien capturé), l'entête est recopiée à partir du fichier de base "typon.bmp" dans le fichier "contour.bmp"

    ensuite le tableau est lu, puis au bout de 8 elements lu, un octet est créé et est écrit dans le fichier.
    voila le code!

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #define source "typon.bmp"
    #define dest "contour.bmp"

    /****************************** *prototype de fonctions********************* *****/
    int main(void);
    void tableau(void);



    /****************************** ***declaration variables********************* ****/
    int bmp[10000][10000];
    int B[8];
    int envoie[8];
    int value, octet;
    short int plan, bitparpixel;
    char ecrit;
    unsigned int offset, largeur, hauteur, compression, echellex, echelley, j, i, k, x, y;
    FILE * fichier1=NULL, * fichier2=NULL;
    /****************************** *******main******************* *******************/
    int main()
    {
    fichier1 = fopen(source, "rb");
    if (fichier1 == NULL)
    {
    printf("impossible d'ouvrir\n");
    system("pause");
    return 0;
    exit(EXIT_FAILURE);
    }

    printf("Fichier ouvert\n");
    fseek(fichier1, 10, SEEK_SET);
    fread(&offset, sizeof(long), 1, fichier1);
    printf("offset : %d\n",offset);
    fseek(fichier1, 18, SEEK_SET);
    fread(&largeur, sizeof(long), 1, fichier1);
    printf("largeur : %d\n", largeur);
    fread(&hauteur, sizeof(long), 1, fichier1);
    printf("hauteur : %d\n", hauteur);
    fread(&plan, sizeof(short), 1, fichier1);
    printf("plan : %d\n", plan);
    fread(&bitparpixel, sizeof(short), 1, fichier1);
    printf("bit(s) par pixel : %d\n", bitparpixel);
    fread(&compression, sizeof(long), 1, fichier1);
    printf("compression (0 si pas de compression) : %d\n", compression);


    fseek(fichier1, 38, SEEK_SET);
    fread(&echellex, sizeof(long), 1, fichier1);
    printf("echelle x : %d\n", echellex);
    fread(&echelley, sizeof(long), 1, fichier1);
    printf("echelle y : %d\n", echelley);
    if (echellex==0) printf("echelle des x inconnue\n");
    if (echelley==0) printf("echelle des y inconnue\n"); // recupère les données du fichier1

    fichier2 = fopen(dest, "wb");
    if (fichier2 == NULL)
    {
    printf("impossible de creer\n");
    system("pause");
    return 0;
    }

    fseek(fichier1, 0, SEEK_SET);
    for (i=0;i<offset;i++)
    {
    fread(&ecrit, sizeof(char), 1, fichier1);
    fprintf(fichier2,"%c",ecrit,fi chier2);
    }

    printf("entête recopiée\n"); // recopie l'entête du fichier1 dans le fichier2
    tableau();
    printf("tableau chargé\n");
    system("pause");


    for (i=0; i<hauteur;i++){ //recopie tableau
    for(k=0;k<largeur;k++){


    envoie[(i*largeur+k)%8]=bmp[k][i];
    if (((i*largeur+k)%8)==7){
    ecrit=envoie[0]*128+envoie[1]*64+envoie[2]*32+envoie[3]*16+envoie[4]*8+envoie[5]*4+envoie[6]*2+envoie[7];
    fprintf(fichier2,"%c",ecrit);
    }

    }}


    fclose(fichier1);
    fclose(fichier2); // fermeture des fichier

    printf("\n\nidentification de contour reussi! resultat exporté dans contour.bmp\n\n");
    system("pause");
    return 0;
    }

    /****************************** ***** tableau*********************** *************/
    void tableau()
    {
    fseek(fichier1, offset, SEEK_SET);
    x=0;
    y=0;
    for (i=0;i<(hauteur*largeur);i++)
    {
    if ((x+y*largeur)%8==0)
    {
    fread(&octet, sizeof(unsigned char), 1, fichier1);
    value=0;
    B[0]=0;
    B[1]=0;
    B[2]=0;
    B[3]=0;
    B[4]=0;
    B[5]=0;
    B[6]=0;

    if (octet-(128+value)>0) { B[0]=1;value=value+128;}
    if (octet-(64+value)>0) { B[1]=1;value=value+64;}
    if (octet-(32+value)>0) { B[2]=1;value=value+32;}
    if (octet-(16+value)>0) { B[3]=1;value=value+16;}
    if (octet-(8+value)>0 ) { B[4]=1;value=value+8;}
    if (octet-(4+value)>0 ) { B[5]=1;value=value+4;}
    if (octet-(2+value)>0 ) { B[6]=1;value=value+2;}
    if (octet-(1+value)>0 ) { B[7]=1;value=value+1;} // decomposition de l'octet lu

    }


    bmp[x][y]=B[(int)(x+y*largeur)%8]; // remplissage du tableau

    x++;
    if (x==largeur){y++;x=0;}; //on passe à la ligne suivante arrivé en bout de ligne

    }


    }

    le code n'est peut être pas très clair...
    le tout étant que le programme se compile, capture l'entête et l'affiche sans problème, recopie l'entête du fichier, mais lors de la recopie du fichier, le nouveau ("contour.bmp") est plus petit et en l'ouvrant avec pain, on voit plein de trait. on distingue le fichier de départ, mais déformé.
    je joins ces deux fichiers.

    j'utilise dev c++ comme programme, mais je suis obligé d'enregistrer mon fichier en *.cpp et de le compiler sinon le programme n'arrive pas à le compiler... c'est peut être la cause de mon problème... mais j'ai déjas fait d'autres petits programme et tout fonctionnait bien donc...

    merci de me dire pourquoi cela ne fonctionne pas, si quelqu'un trouve... j'ai essayé plusieurs choses mais je n'ai pas encore trouvé si cela vien de la copie dans le tableau ou de la restitution...

    Merci d'avance
    Olivier

    Pour poster des images de ce type le format gif est bien mieux adapté : aucune perte de qualité et poids bien plus faible : voir http://forums.futura-sciences.com/el...ointes-pj.html
    JPL, modérateur

    -----
    Images attachées Images attachées
    Dernière modification par JPL ; 02/11/2008 à 12h27.

  2. Publicité
  3. #2
    Jean_Luc

    Re : enregistrement fichier bmp dans tableau, puis restitution

    Salut,

    Prends tu en compte le "bitparpixel" ?
    Tu dois écrire bitparpixel bits par pixel

    Tu utilises fprintf() pour écrire dans un fichier binaire. Je ne suis pas sur que ça marche comme tu le souhaites.
    Essaye plutôt d'écrire avec fwrite()
    ex:
    Code:
    // Ecrit 8 bits
    char c;
    fwrite(&c, sizeof(char), 1, fichier);
    ou
    Code:
    // Ecrit 32 bits
    long l;
    fwrite(&l, sizeof(long), 1, fichier);
    L'Univers est fini. Ah bon déjà ?

  4. #3
    olver62

    Re : enregistrement fichier bmp dans tableau, puis restitution

    merci pour ta réponse!
    le bitparpixel était pour verifier que le fichier d'entrée est monochrome (=1), ce qui est le cas.

    j'ai remplacé "fprintf" par "fwrite" mais le fichier de sortie est le même..., le problème n'est pas résolu même si fwrite est plus aproprié...

    si vous d'autres suggestion, merci!
    salutations
    Olivier

  5. #4
    Jean_Luc

    Re : enregistrement fichier bmp dans tableau, puis restitution

    Si bitparpixel=1 alors tu dois lire et écrire 1 bit par pixel et pas un char (8bits)

    J'attends que tes pièces jointes soit validées...
    L'Univers est fini. Ah bon déjà ?

  6. A voir en vidéo sur Futura
  7. #5
    olver62

    Re : enregistrement fichier bmp dans tableau, puis restitution

    oui! je suis tout à fait d'accord, je doit écrire un bit par pixel! mais n'ayant pas trouvé la fonction qui permetd'ecrire un seul pixel, j'en regroupe 8 pour former un char que j'écrit dans le fichier texte!
    ecrit=envoie[0]*128+envoie[1]*64+envoie[2]*32+envoie[3]*16+envoie[4]*8+envoie[5]*4+envoie[6]*2+envoie[7];
    mais il y a peut être une erreur dans l'ordre de reassemblage... je vais regarder à ca!
    merci!

  8. #6
    Jean_Luc

    Re : enregistrement fichier bmp dans tableau, puis restitution

    Ok, en fait j'avais pas vu le test
    if (((i*largeur+k)%8)==7){

    Je pense qu'il y a un problème de padding comme 284 n'est pas divisible par 8 il faut écrire 4 bits supplémentaire par ligne.

    Il faut modifier ton algo pour prendre en compte ce décalage.
    (il manque bien 364/2 octet a ton fichier).
    L'Univers est fini. Ah bon déjà ?

  9. Publicité
  10. #7
    Towl

    Re : enregistrement fichier bmp dans tableau, puis restitution

    Pourquoi n'utilises tu pas les masques et les décalages pour lire tes données ? C'est en général plus simple et moinslong à écrire
    Aussi, je sens un probleme de signe, ecrit est un signed char, or pour ce genre de truc, je préfere toujours les unsigned char. Au moins, tu n'as pas de complement A2 silencieux qui va se faire.

    Un exemple de lecture avec les masques :

    Code:
    //
    // data : les donnees a convertir en bytes
    // bytes : un tableau de 8
    //
    void charToBytes(const unsigned char data, unsigned char *bytes)
    {
    	unsigned char l = 8;
    	unsigned char mask = 0x01;
    	assert(bytes != NULL)
    	// 8 petits tours pour lire les 8 bits 
    	while( l--)
    	{
    		// on masque data et on stocke le resultat dans la ieme case du tableau 
    		*bytes = data & mask;
    		// on passe à la case suivante du tableau de bytes 
    		bytes++;
    		// On effectue un décalage sur le masque (ie mask = mask *2)
    		mask <= 1;
    	}
    }
    Et il te suffit de faire
    Code:
    fread(&octet, sizeof(unsigned char), 1, fichier1);
    charToBytes(octet, B);
    Au lieu de
    Code:
    fread(&octet, sizeof(unsigned char), 1, fichier1);
    value=0;
    B[0]=0;
    B[1]=0;
    B[2]=0;
    B[3]=0;
    B[4]=0;
    B[5]=0;
    B[6]=0;
    
    if (octet-(128+value)>0) { B[0]=1;value=value+128;}
    if (octet-(64+value)>0) { B[1]=1;value=value+64;}
    if (octet-(32+value)>0) { B[2]=1;value=value+32;}
    if (octet-(16+value)>0) { B[3]=1;value=value+16;}
    if (octet-(8+value)>0 ) { B[4]=1;value=value+8;}
    if (octet-(4+value)>0 ) { B[5]=1;value=value+4;}
    if (octet-(2+value)>0 ) { B[6]=1;value=value+2;}
    if (octet-(1+value)>0 ) { B[7]=1;value=value+1;} // decomposition de l'octet lu
    The only limiting factor of the Linux operating system, is his user. - Linus Torvalds

  11. #8
    Towl

    Re : enregistrement fichier bmp dans tableau, puis restitution

    Pour eviter de se prendre la tete avec les lignes et les colones, je te conseilles de faire un tableau unidimensionel de facon à ce que le pixel de la colone X et de la ligne Y puisse etre obtenu par tab[Y*<taille d'une ligne> + X] (ex pour un 8*8 : tab[3*8 + 4] ==> 4eme colonne, 3eme ligne)

    Comme ca, aucun soucis pour le changement de ligne, et la lecture reste assez simple
    The only limiting factor of the Linux operating system, is his user. - Linus Torvalds

  12. #9
    Jean_Luc

    Re : enregistrement fichier bmp dans tableau, puis restitution

    En faisant les petites modifications suivantes le programme marche
    mais pour des largeurs multiples de 32bits (cas ou il n'y a pas
    de padding).
    J'ai essayé en retaillant ton image de départ en 288x364.

    Bien sur pour une fonction tableau encore plus propre tu
    peux utiliser la méthode du masque que présente Towl

    Code:
    ecrit=envoie[0]*128+envoie[1]*64+envoie[2]*32+envoie[3]*16+envoie[4]*8+envoie[5]*4+envoie[6]*2+envoie[7];
    
    
    void tableau()
    {
      fseek(fichier1, offset, SEEK_SET);
      for (y=0;y<hauteur;y++)
        for (x=0;x<largeur;x++)
        {
          if ((x+y*largeur)%8==0)
          {
            fread(&octet, sizeof(unsigned char), 1, fichier1);
            B[0] = (octet & 0x80)?1:0;
            B[1] = (octet & 0x40)?1:0;
            B[2] = (octet & 0x20)?1:0;
            B[3] = (octet & 0x10)?1:0;
            B[4] = (octet & 0x08)?1:0;
            B[5] = (octet & 0x04)?1:0;
            B[6] = (octet & 0x02)?1:0;
            B[7] = (octet & 0x01)?1:0;
          }
          bmp[x][y]=B[(int)(x+y*largeur)%8]; // remplissage du tableau
        }
    
    }
    L'Univers est fini. Ah bon déjà ?

  13. #10
    Towl

    Re : enregistrement fichier bmp dans tableau, puis restitution

    En lisant ton code, je me suis apercu d'une simplifaction que j'avais faite naturellement dans mon code mais qui peut poser des problemes à certains
    En effet, je stocke 0 si je masque un 0, et je stocke autre chose (1, 2, 4, 8....) dans le cas contraire.

    Pour stocker 0 ou 1, tu peux utiliser :
    Code:
    *bytes = data & mask ? 1 : 0;
    Tout dépend de ce que tu souhaites faire.
    The only limiting factor of the Linux operating system, is his user. - Linus Torvalds

  14. #11
    Jean_Luc

    Re : enregistrement fichier bmp dans tableau, puis restitution

    Avec les modifications suivantes ça devrait marcher pour toutes
    les tailles.

    Code:
    int lineSize;
    
    ...
    
    lineSize = (largeur%32==0)?largeur:(largeur/32+1) * 32;
    
    printf("entête recopiée\n"); // recopie l'entête du fichier1 dans le fichier2
    tableau();
    printf("tableau chargé\n");
    system("pause");
    
    
    for (i=0; i<hauteur;i++){ //recopie tableau
    for(k=0;k<lineSize;k++){
    
    
    envoie[(i*lineSize+k)%8]=bmp[k][i];
    if (((i*lineSize+k)%8)==7){
    ecrit=envoie[0]*128+envoie[1]*64+envoie[2]*32+envoie[3]*16+envoie[4]*8+envoie[5]*4+envoie[6]*2+envoie[7];
    fwrite(&ecrit,1,1,fichier2);
    }
    
    ...
    
    void tableau()
    {
    
      fseek(fichier1, offset, SEEK_SET);
      for (y=0;y<hauteur;y++)
        for (x=0;x<lineSize;x++)
        {
          if ((x+y*lineSize)%8==0)
          {
            fread(&octet, sizeof(unsigned char), 1, fichier1);
            B[0] = (octet & 0x80)?1:0;
            B[1] = (octet & 0x40)?1:0;
            B[2] = (octet & 0x20)?1:0;
            B[3] = (octet & 0x10)?1:0;
            B[4] = (octet & 0x08)?1:0;
            B[5] = (octet & 0x04)?1:0;
            B[6] = (octet & 0x02)?1:0;
            B[7] = (octet & 0x01)?1:0;
          }
          bmp[x][y]=B[(int)(x+y*lineSize)%8]; // remplissage du tableau
        }
    
    }
    L'Univers est fini. Ah bon déjà ?

  15. #12
    olver62

    Re : enregistrement fichier bmp dans tableau, puis restitution

    bonjour à tous et merci beaucoup pour vos réponses!! étant débutant en C, je ne conaissais pas les masques! comme ca j'ai appris quelque chose! et le code est déjas plus propre!
    en suivant les conseils de Towl, j'ai bien redéclaré mes variables "unsigned"

    et depuis, le programme ce comporte bien mieu!!
    j'ai toujours quelques octets de moins, mais l'image de sortie est identique à l'image d'entrée, si ce n'est qu'en sortie, il y a des pixels noirs tout en haut, qui aparraissent sur quelques ligne (le nombre de ligne dépend de la taille du fichier de depart)... sinon tout le reste est très correct!

    étant donné que ce sont les lignes du haut, le problème doit se passer à la fin du fichier! (construction d'un fichier bmp)
    en ouvrant les fichiers bmp avec le bloc note, je remarque qu'il manque quelques lignes de caratère pour le fichier bmp. je pense que les lignes qui apparaissent noir sont due au fait qu'il n'y a pas de carractère dans le fichier (paint rempli donc comme il peut...) est-ce correct?

    par contre je n'ai aucune idée d'où cela peut provenir..., mes boucles ont l'air correctes au niveau des indices...
    je vais aller verifier comment se structire un fichier bmp ...

    merci de me dire si quelqu'un sait de quoi cela peut provenir!


    état du code actuel:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #define source "typon.bmp"
    #define dest "contour.bmp"

    /****************************** *prototype de fonctions********************* *****/
    int main(void);
    void tableau(void);



    /****************************** ***declaration variables********************* ****/
    unsigned char bmp[10000][10000];
    unsigned char B[8];
    unsigned char envoie[8];
    unsigned char value, octet;
    short int plan, bitparpixel;
    unsigned char ecrit;
    unsigned int offset, largeur, hauteur, compression, echellex, echelley, x, y;
    FILE * fichier1=NULL, * fichier2=NULL;
    /****************************** *******main******************* *******************/
    int main()
    {
    fichier1 = fopen(source, "rb");
    if (fichier1 == NULL)
    {
    printf("impossible d'ouvrir\n");
    system("pause");
    return 0;
    exit(EXIT_FAILURE);
    }

    printf("Fichier ouvert\n");
    fseek(fichier1, 10, SEEK_SET);
    fread(&offset, sizeof(long), 1, fichier1);
    printf("offset : %d\n",offset);
    fseek(fichier1, 18, SEEK_SET);
    fread(&largeur, sizeof(long), 1, fichier1);
    printf("largeur : %d\n", largeur);
    fread(&hauteur, sizeof(long), 1, fichier1);
    printf("hauteur : %d\n", hauteur);
    fread(&plan, sizeof(short), 1, fichier1);
    printf("plan : %d\n", plan);
    fread(&bitparpixel, sizeof(short), 1, fichier1);
    printf("bit(s) par pixel : %d\n", bitparpixel);
    fread(&compression, sizeof(long), 1, fichier1);
    printf("compression (0 si pas de compression) : %d\n", compression);


    fseek(fichier1, 38, SEEK_SET);
    fread(&echellex, sizeof(long), 1, fichier1);
    printf("echelle x : %d\n", echellex);
    fread(&echelley, sizeof(long), 1, fichier1);
    printf("echelle y : %d\n", echelley);
    if (echellex==0) printf("echelle des x inconnue\n");
    if (echelley==0) printf("echelle des y inconnue\n"); // recupère les données du fichier1

    fichier2 = fopen(dest, "wb");
    if (fichier2 == NULL)
    {
    printf("impossible de creer\n");
    system("pause");
    return 0;
    }

    fseek(fichier1, 0, SEEK_SET);
    for (x=0;x<offset;x++)
    {
    fread(&ecrit, sizeof(char), 1, fichier1);
    fprintf(fichier2,"%c",ecrit,fi chier2);
    }

    printf("entête recopiée\n"); // recopie l'entête du fichier1 dans le fichier2
    tableau();
    printf("tableau chargé\n");
    system("pause");


    for (y=0; y<hauteur;y++){ //recopie tableau
    for(x=0;x<largeur;x++){


    envoie[(y*largeur+x)%8]=bmp[x][y];
    if (((y*largeur+x)%8)==7){
    ecrit=envoie[0]*128+envoie[1]*64+envoie[2]*32+envoie[3]*16+envoie[4]*8+envoie[5]*4+envoie[6]*2+envoie[7];
    fprintf(fichier2,"%c",ecrit);
    }

    }}


    fclose(fichier1);
    fclose(fichier2); // fermeture des fichier

    printf("\n\nidentification de contour reussi! resultat exporté dans contour.bmp\n\n");
    system("pause");
    return 0;
    }

    /****************************** ***** tableau*********************** *************/

    void tableau()
    {
    fseek(fichier1, offset, SEEK_SET);
    for (y=0;y<hauteur;y++)
    for (x=0;x<largeur;x++)
    {
    if ((x+y*largeur)%8==0)
    {
    fread(&octet, sizeof(unsigned char), 1, fichier1);
    B[0] = (octet & 0x80)?1:0;
    B[1] = (octet & 0x40)?1:0;
    B[2] = (octet & 0x20)?1:0;
    B[3] = (octet & 0x10)?1:0;
    B[4] = (octet & 0x08)?1:0;
    B[5] = (octet & 0x04)?1:0;
    B[6] = (octet & 0x02)?1:0;
    B[7] = (octet & 0x01)?1:0;
    }
    bmp[x][y]=B[(int)(x+y*largeur)%8]; // remplissage du tableau
    }

    }


  16. Publicité
  17. #13
    olver62

    Re : enregistrement fichier bmp dans tableau, puis restitution

    je n'avais pas vu ton message jean-luc! je vais l'incorporer dans le code! merci!

  18. #14
    olver62

    Re : enregistrement fichier bmp dans tableau, puis restitution

    je n'ai qu'une chose à dire, merci à tous!!!! le programme fonctionne, le tableau se rempli bien, je peux donc continuer mon programme!

    bon fin d'après midi!!
    salutations
    Olivier



    si jamais quelqu'un veux le code final:


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #define source "typon.bmp"
    #define dest "contour.bmp"
    
    /****************************** *prototype de fonctions********************* *****/
    int main(void);
    void tableau(void);
    
    
    
    /****************************** ***declaration variables********************* ****/
    int lineSize;
    unsigned char bmp[10000][10000];
    unsigned char B[8];
    unsigned char envoie[8];
    unsigned char value, octet;
    short int plan, bitparpixel;
    unsigned char ecrit;
    unsigned int offset, largeur, hauteur, compression, echellex, echelley, x, y;
    FILE * fichier1=NULL, * fichier2=NULL;
    /****************************** *******main******************* *******************/
    int main()
    {
    fichier1 = fopen(source, "rb"); 
    if (fichier1 == NULL)
    { 
    printf("impossible d'ouvrir\n");
    system("pause");
    return 0;
    exit(EXIT_FAILURE);
    }
    
    printf("Fichier ouvert\n");
    fseek(fichier1, 10, SEEK_SET);
    fread(&offset, sizeof(long), 1, fichier1);
    printf("offset : %d\n",offset);
    fseek(fichier1, 18, SEEK_SET);
    fread(&largeur, sizeof(long), 1, fichier1);
    printf("largeur : %d\n", largeur);
    fread(&hauteur, sizeof(long), 1, fichier1);
    printf("hauteur : %d\n", hauteur);
    fread(&plan, sizeof(short), 1, fichier1);
    printf("plan : %d\n", plan);
    fread(&bitparpixel, sizeof(short), 1, fichier1);
    printf("bit(s) par pixel : %d\n", bitparpixel);
    fread(&compression, sizeof(long), 1, fichier1);
    printf("compression (0 si pas de compression) : %d\n", compression);
    
    
    fseek(fichier1, 38, SEEK_SET);
    fread(&echellex, sizeof(long), 1, fichier1);
    printf("echelle x : %d\n", echellex);
    fread(&echelley, sizeof(long), 1, fichier1);
    printf("echelle y : %d\n", echelley);
    if (echellex==0) printf("echelle des x inconnue\n");
    if (echelley==0) printf("echelle des y inconnue\n"); // recupère les données du fichier1
    
    fichier2 = fopen(dest, "wb");
    if (fichier2 == NULL)
    {
    printf("impossible de creer\n");
    system("pause");
    return 0;
    }
    
    fseek(fichier1, 0, SEEK_SET);
    for (x=0;x<offset;x++)
    {
    fread(&ecrit, sizeof(char), 1, fichier1);
    fprintf(fichier2,"%c",ecrit,fichier2);
    }
    
    
    lineSize = (largeur%32==0)?largeur:(largeur/32+1) * 32;
    
    printf("entête recopiée\n"); // recopie l'entête du fichier1 dans le fichier2
    tableau();
    printf("tableau chargé\n");
    system("pause");
    
    
    for (y=0; y<hauteur;y++){ //recopie tableau
    for(x=0;x<lineSize;x++){
    
    
    envoie[(y*lineSize+x)%8]=bmp[x][y];
    if (((y*lineSize+x)%8)==7){
    ecrit=envoie[0]*128+envoie[1]*64+envoie[2]*32+envoie[3]*16+envoie[4]*8+envoie[5]*4+envoie[6]*2+envoie[7];
    fprintf(fichier2,"%c",ecrit);
    }
    
    }}
    
    
    fclose(fichier1);
    fclose(fichier2); // fermeture des fichier
    
    printf("\n\nidentification de contour reussi! resultat exporté dans contour.bmp\n\n");
    system("pause"); 
    return 0; 
    }
    
    /****************************** ***** tableau*********************** *************/
    
    void tableau()
    {
      fseek(fichier1, offset, SEEK_SET);
      for (y=0;y<hauteur;y++)
        for (x=0;x<lineSize;x++)
        {
          if ((x+y*lineSize)%8==0)
          {
            fread(&octet, sizeof(unsigned char), 1, fichier1);
            B[0] = (octet & 0x80)?1:0;
            B[1] = (octet & 0x40)?1:0;
            B[2] = (octet & 0x20)?1:0;
            B[3] = (octet & 0x10)?1:0;
            B[4] = (octet & 0x08)?1:0;
            B[5] = (octet & 0x04)?1:0;
            B[6] = (octet & 0x02)?1:0;
            B[7] = (octet & 0x01)?1:0;
          }
          bmp[x][y]=B[(int)(x+y*lineSize)%8]; // remplissage du tableau
        }
    
    }
    Dernière modification par yoda1234 ; 02/11/2008 à 22h21. Motif: Modification balises

  19. #15
    Towl

    Re : enregistrement fichier bmp dans tableau, puis restitution

    Puisque tu sembles souhaiter apprendre le C et ses astuces, regarde du coté des structures pour ton image, cela pourra etre interressant. Un exemple bidon de structure pouvant te convenir :
    Code:
    typedef struct
    {
        unsigned int height;
        unsigned int height;
        unsigned char pixels[10000][10000]; // en attendant que tu t'amuses avec les mallocs ;)
    }bitmap;
    
    // et pour l'utilisation :
    int main()
    {
        bitmap img;
        img.heigth = 20;
        ...
        img.pixels[1][10] = 0;
        ....
        printBitmap(&img);
    }
    
    printBitmap(bitmap *img)
    {
        printf("Hauteur = %ul\n", img->height);
        ....
    }

    L'avantage des structure c'est d'avoir toutes les données necessaire dans une seule variable, ce qui eviter de passer 36 000 parametres aux fonctions, et permet aussi de garder une cohérence d'écriture.

    Sinon, pour les codes, utilise plutot la balise code que citation, ca permet de garder l'indentation
    The only limiting factor of the Linux operating system, is his user. - Linus Torvalds

  20. #16
    Jean_Luc

    Re : enregistrement fichier bmp dans tableau, puis restitution

    Oui, les structures c'est très pratique, et celles dont tu as besoin
    sont déjà définies pour toi en incluant <windows.h>
    Du moins si tu bosses sur Windows...

    Code:
    #include <windows.h>
    
    ...
    
    BITMAPFILEHEADER fHeader;     // Header du BMP
    BITMAPINFOHEADER infoHeader;  // Header du BMP
    RGBQUAD colors[2];            // Monochrome => 2 colors
    
    ...
    
    int main(int argc, char **argv)
    {
    
    
      fichier1 = fopen(source, "rb");
      if (fichier1 == NULL)
      {
        printf("impossible d'ouvrir\n");
        system("pause");
        return 0;
        exit(EXIT_FAILURE);
      }
    
      fread(&fHeader,sizeof(BITMAPFILEHEADER),1,fichier1);
      fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,fichier1);
      fread(colors,sizeof(RGBQUAD),2,fichier1);
    
      printf("Fichier ouvert\n");
      printf("offset : %d\n",fHeader.bfOffBits);
      printf("largeur : %d\n", infoHeader.biWidth);
      printf("hauteur : %d\n", infoHeader.biHeight);
      printf("plan : %d\n", infoHeader.biPlanes);
      printf("bit(s) par pixel : %d\n", infoHeader.biBitCount);
      printf("compression (0 si pas de compression) : %d\n", infoHeader.biCompression);
      printf("echelle x : %d\n", infoHeader.biXPelsPerMeter);
      printf("echelle y : %d\n", infoHeader.biYPelsPerMeter);
    
    ...
    L'Univers est fini. Ah bon déjà ?

  21. #17
    Towl

    Re : enregistrement fichier bmp dans tableau, puis restitution

    et celles dont tu as besoin sont déjà définies pour toi en incluant <windows.h>
    Erk, comment faire du C compilable uniquement sous windows en une seule ligne
    Franchement, eviter autant que possible ce genre d'include un poil trop spécifique, préférer ceux définit dans des bibliotheques C standard et dispo sous tout OS style glib. Ainsi on prend directement de bonnes habitudes et si un jour on à a coder sous un autre OS, on a besoin de rien modifier.
    The only limiting factor of the Linux operating system, is his user. - Linus Torvalds

  22. #18
    Jean_Luc

    Re : enregistrement fichier bmp dans tableau, puis restitution

    Tout a fait d'accord.
    Dans ce cas on peut redéfinir les structures soit même.
    Juste quelques petits cut and paste de la doc Windows
    Si on veut aller jusqu'au bout, il faut aussi respecter le little endian sinon ça ne marchera que sur des plates-formes a base de CPU Intels.
    L'Univers est fini. Ah bon déjà ?

  23. Publicité
  24. #19
    olver62

    Re : enregistrement fichier bmp dans tableau, puis restitution

    merci pour tout ces complement! je ne connaissais pas les structures... merci!
    je les incorporerrais peut être dans le code pour éclaircir les declarations de variables...

    sinon j'ai poursuivi mon programme, je ne vous l'ai pas dit mais j'aimerrais que ce programme analyse un fichier typon.bmp et qu'il genaire un fichier *.iso ou *.txt contenant du g-code. ce dernier serra interpretté par une fraiseuse numérique.

    grâce à votre aide, j'ai réussi à creer le tableauà partir du fichier, d'en créer un autre avec le contour des pistes(bandes noires)de largeur 1 pixel et maintennant je suis dans le suivit des lignes (si vous n'avez pas tout compris ce n'est pas grave, j'explique mal).

    le fait étant que j'ai besoin d'écrire dans le fichier et de retourner à la ligne assez souvent. je pensais utiliser fprinf(fichier3,"\n"); mais dans le fichier final il n'y a aucun retour chariot... je n'ai rien trouvé dans les forums...
    ma fonction est celle la:
    fprintf(fichier3,"N%d G01 X%f Y%f\n",ligne,((float)x)*echell e,((float)y)*echelle);

    si vous avez des idées... (désolé de vous déranger encore et un dimanche en plus...)

    merci d'avance
    Olivier

  25. #20
    Jean_Luc

    Re : enregistrement fichier bmp dans tableau, puis restitution

    Bizarre...
    Essaye en remplaçant le "\n" par "\r\n".
    L'Univers est fini. Ah bon déjà ?

  26. #21
    olver62

    Re : enregistrement fichier bmp dans tableau, puis restitution

    merci!! ca fonctionne!!!

  27. #22
    olver62

    Smile Re : enregistrement fichier bmp dans tableau, puis restitution

    bon, je vien de finir mon programme, après plusieurs erreurs qui sont maintennant corrigées (ou bidouillées pour que ca marche...) mon programme fonctionne!!
    j'envoie le code pour ceux qui le souhaitent. ce programme permet donc de convertir un fichier bmp monochrome (issus de proteus pour moi) en fichier *.tap lisible par mach3!
    voila!
    le code est loin d'être optimisé, mais il fonctionne... il faut juste être patient...
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #define source "typon.bmp"
    #define dest "contour.bmp"
    #define iso  "g-code.tap"
    
    /****************************** *prototype de fonctions********************* *****/
    int main(void);
    void tableau(void);
    int fcontour(unsigned int ,unsigned int );
    int verif(void);
    
    /****************************** ***declaration variables********************* ****/
    int lineSize, DPI, echap, fin;
    unsigned char bmp[10000][10000];
    unsigned char contour[10000][10000];
    unsigned char B[8];
    unsigned char envoie[8];
    unsigned char value, octet;
    short int plan, bitparpixel;
    unsigned char ecrit;
    unsigned int offset, largeur, hauteur, compression, echellex, echelley, x, y,k,l,i,j, ligne;
    
    float echelle, taille;
    FILE * fichier1=NULL, * fichier2=NULL, *fichier3=NULL;
    /****************************** *******main******************* *******************/
    int main()
    {
    fichier1 = fopen(source, "rb"); 
    
    if (fichier1 == NULL)
        { 
        printf("impossible d'ouvrir\n");
        system("pause");
        return 0;
        exit(EXIT_FAILURE);
        }
    
    printf("Fichier ouvert\n");
    fseek(fichier1, 10, SEEK_SET);
    fread(&offset, sizeof(long), 1, fichier1);
    printf("offset : %d\n",offset);
    fseek(fichier1, 18, SEEK_SET);
    fread(&largeur, sizeof(long), 1, fichier1);
    printf("largeur : %d\n", largeur);
    fread(&hauteur, sizeof(long), 1, fichier1);
    printf("hauteur : %d\n", hauteur);
    fread(&plan, sizeof(short), 1, fichier1);
    printf("plan : %d\n", plan);
    fread(&bitparpixel, sizeof(short), 1, fichier1);
    printf("bit(s) par pixel : %d\n", bitparpixel);
    fread(&compression, sizeof(long), 1, fichier1);
    printf("compression (0 si pas de compression) : %d\n", compression);
    
    
    fseek(fichier1, 38, SEEK_SET);
    fread(&echellex, sizeof(long), 1, fichier1);
    printf("echelle x : %d\n", echellex);
    fread(&echelley, sizeof(long), 1, fichier1);
    printf("echelle y : %d\n", echelley);
    if (echellex==0|echelley==0) {
                                 printf("echelle des x inconnue\n entrez l'echelle du fichier en DPI ou pixel par pouces :");
                                 scanf("%d",&DPI);
                                 }
    echelle=(((float)24.5)/(float)DPI);
    printf("\ndistance entre deux pixels :%f\n",echelle);
    printf("entrez la profondeur de taille en mm :");
    scanf("%f",&taille);
    
     // recupère les données du fichier1
    
    fichier2 = fopen(dest, "wb");
    if (fichier2 == NULL)
                         {
                         printf("impossible de creer\n");
                         system("pause");
                         return 0;
                         }
    
    fseek(fichier1, 0, SEEK_SET);
    
    for (x=0;x<offset;x++)
                          {
                          fread(&ecrit, sizeof(char), 1, fichier1);
                          fprintf(fichier2,"%c",ecrit,fichier2);
                          }
    
    
    lineSize = (largeur%32==0)?largeur:(largeur/32+1) * 32;
    printf("\nlineSize :%d\n",lineSize);
    
    for (y=0;y<hauteur;y++){for (x=0;x<lineSize;x++){contour[x][y]=1;}}  //initialisation du tableau contour
    tableau();
    printf("tableau chargé\n");
    system("pause");
    
    for (y=1;y<(hauteur-1);y++){
                                for (x=1;x<(lineSize-1);x++){
                                                              if (fcontour(x,y)==1) {contour[x][y]=0;}
                                                              }
                                }
    for(y=0;y<hauteur;y++){contour[lineSize-1][y]=1;}
    
    printf("entête recopiée\n"); // recopie l'entête du fichier1 dans le fichier2
    
    for (y=0; y<hauteur;y++){ //recopie tableau
                            for(x=0;x<lineSize;x++){
                                                    envoie[(y*lineSize+x)%8]=contour[x][y];
                                                     if (((y*lineSize+x)%8)==7){
                                                                                 ecrit=envoie[0]*128+envoie[1]*64+envoie[2]*32+envoie[3]*16+envoie[4]*8+envoie[5]*4+envoie[6]*2+envoie[7];
                                                                                 fprintf(fichier2,"%c",ecrit);
                                                                                }
                                                   }
                            }
    
    
    fclose(fichier1);
    fclose(fichier2); // fermeture des fichier
    
    printf("\n\nidentification de contour reussi! resultat exporté dans contour.bmp\n\n");
    system("pause"); 
    
    
    fichier3 = fopen(iso, "wb"); 
    if (fichier3 == NULL){ 
                           printf("impossible de creer g-code.iso\n");
                           system("pause");
                           return 0;
                           exit(EXIT_FAILURE);
                           }
    
    
    fprintf(fichier3,"%1%\r\nN1 ( This file is created by olivier s programm )\r\nN2 G17 T1\r\nN3 G64\r\nN4 S10000 M3\r\nN5 M8\r\nN6 G00 X0 Y0 Z2\r\nN7 F3000\r\n");
    ligne=8;
    i=1;
    j=1;
                                                      do {
    if (contour[i][j]==0){
                            fprintf(fichier3,"N%d G00 X%f Y%f\r\n",ligne,((float)i*echelle),((float)j*echelle));
                            ligne++;
                            fprintf(fichier3,"N%d Z%f\r\n",ligne,taille);
                            ligne++;
                            k=i;
                            l=j;
                            echap=1;
                                                  do {
                                                   fprintf(fichier3,"N%d G01 X%f Y%f\r\n",ligne,((float)i*echelle),((float)j*echelle));
                                                   ligne++; 
                                                   contour[i][j]=1;
                                                   contour[k][l]=0;
                                                   if (j<1|j>hauteur|i<1|i>largeur){echap=0;}
                                                   if (contour[i+1][j]==0) {i=i+1;}
                                                   else if (contour[i-1][j]==0) {i=i-1;}
                                                   else if (contour[i][j+1]==0) {j=j+1;}                                        
                                                   else if (contour[i][j-1]==0) {j=j-1;}
                                                   else if ((contour[i+1][j]!=0)&(contour[i-1][j]!=0)&(contour[i][j+1]!=0)&(contour[i][j-1]!=0)){echap=0;}                     
                                                   
                                                    }while((k!=i|l!=j)&echap);
                            contour[k][l]=1;
                            fprintf(fichier3,"N%d G01 Z%d\r\n",ligne,0);
                            ligne++;
                            i=1;
                            j=1;
                            }
    i++;
    if (i==(largeur-10)){i=1;j++;}
    if (j==hauteur+1) {printf("\ndepassement de la hauteur du fichier. operation terminée\n\n"); system("pause"); fin=1;}
    
    
    
                                                    } while (fin==0);
    
    
    
    
    fprintf(fichier3,"N%d G00 X0 Y0\r\n");
    
    
    return 0; 
    }
    
    
    
    
    
    
    
    
    
    
    /****************************** ***** tableau*********************** *************/
    
    void tableau()
    {
      fseek(fichier1, offset, SEEK_SET);
      for (y=0;y<hauteur;y++)
        for (x=0;x<lineSize;x++)
        {
          if ((x+y*lineSize)%8==0)
          {
            fread(&octet, sizeof(unsigned char), 1, fichier1);
            B[0] = (octet & 0x80)?1:0;
            B[1] = (octet & 0x40)?1:0;
            B[2] = (octet & 0x20)?1:0;
            B[3] = (octet & 0x10)?1:0;
            B[4] = (octet & 0x08)?1:0;
            B[5] = (octet & 0x04)?1:0;
            B[6] = (octet & 0x02)?1:0;
            B[7] = (octet & 0x01)?1:0;
          }
          bmp[x][y]=B[(int)(x+y*lineSize)%8]; // remplissage du tableau
        }
    
    }
    
    /********************************* contour ***************************************/
    int fcontour(unsigned int x,unsigned int y)
    {
             if (bmp[x][y]==0){return 0;}
             
             if (bmp[x-1][y+1]*bmp[x][y+1]*bmp[x+1][y+1]*bmp[x-1][y]*bmp[x+1][y]*bmp[x-1][y-1]*bmp[x][y-1]*bmp[x+1][y-1]==0){return 1;}
    
    
             return 0;
    }
    /**********************************verif******************************************/
    int verif()
    {
        for (y=0;y<hauteur;y++){
        for (x=0;x<lineSize;x++){
            if (contour[x][y]==1) return 0;
            }}
            
            return 1;
    }
    ps: inclure le fichier *.bmp dans le même dossier que l'exe compilé pour que ca fontionne

    merci @ tous pour votre aide sans laquelle je n'aurrais rien pu faire!!

    Salutations
    Olivier

Discussions similaires

  1. Matlab Lecture de n fichier .txt et ecriture dans un fichier .xls
    Par yokute dans le forum Logiciel - Software - Open Source
    Réponses: 4
    Dernier message: 26/07/2010, 09h12
  2. Fichier .doc dans fichier .pdf
    Par Apodis dans le forum Logiciel - Software - Open Source
    Réponses: 5
    Dernier message: 25/09/2008, 21h09
  3. Comment exporter un tableau (.xls ou .ods) en fichier .dat? (pour Gauss)
    Par Zalyo dans le forum Logiciel - Software - Open Source
    Réponses: 2
    Dernier message: 09/08/2007, 09h55
  4. furby_moding : enregistrement/restitution de sons.
    Par Tix dans le forum Électronique
    Réponses: 9
    Dernier message: 07/10/2006, 17h16
  5. enregistrement/restitution des ultrasons
    Par Jean-Paul dans le forum Technologies
    Réponses: 5
    Dernier message: 14/12/2004, 14h53
Découvrez nos comparatifs produits sur l'informatique et les technologies.