Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

Sujet : Ecriture d'un fichier BMP "à l'ancienne" [ Windows / Multimédia ] (MaxSoldier)

mardi 4 décembre 2007 à 11:21:42 | Ecriture d'un fichier BMP "à l'ancienne"

MaxSoldier

Membre Club

Salut à tous ! N'ayant pas pus résoudre mon prblème seul, je m'en réfère à vous !
Je m'explique, je cherche à écrire un fichier BMP à l'ancienne, c'est à dire sans aucune librairie.
Je suis presque au bout de mon programme mais lorsque je lui demande de dessiner un pixel, il dessine tout les ligne horizontale. A quoi est-ce du ?

Voici mon code :



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

// Structs
typedef struct{
 unsigned char Red;
 unsigned char Green;
 unsigned char Blue;
}Color;

typedef struct
{
 Color* ImgArray;

 char* Filename;
 int iWidth;
 int iHeight;

 FILE* FS;
}Picture;

void InitBmpFile(FILE *FS,unsigned int iWidth,unsigned int iHeight);

Picture BuildPicture(char* Filename,unsigned int iWidth,unsigned int iHeight)
{
 Picture TmpPic;

 TmpPic.Filename = Filename;
 TmpPic.FS = fopen(Filename,"wb");

 TmpPic.iWidth = iWidth;
 TmpPic.iHeight = iHeight;

 TmpPic.ImgArray = (Color*)malloc((sizeof(Color)*iWidth) + (sizeof(Color)*iHeight));
 
 InitBmpFile(TmpPic.FS,iWidth,iHeight);

 return TmpPic;
}

void InitBmpFile(FILE *FS,unsigned int iWidth,unsigned int iHeight)
{
 const char *BMFormat = "BM";
 unsigned int BMPHeaderLenght = (iWidth*iHeight*3) + 54;
 unsigned int ReservedBit = 0;
 unsigned int DataOffset = 54;

 unsigned int DataHeaderLenght = 40;
 unsigned short Planes = 1;
 unsigned short BPP = 24;

 unsigned int Compression = 0;

 unsigned int ImageSize = 0;//(iWidth*iHeight*3);

 unsigned int ResX = 0;
 unsigned int Resy = 0;

 unsigned int ColorUsed =0;
 unsigned int ColorImportant = 0;

 fwrite(BMFormat,1,2,FS);
 fwrite(&BMPHeaderLenght,4,1,FS);
 fwrite(&ReservedBit,4,1,FS);
 fwrite(&DataOffset,4,1,FS);
 
 fwrite(&DataHeaderLenght,4,1,FS);
 fwrite(&iWidth,4,1,FS);
 fwrite(&iHeight,4,1,FS);

 fwrite(&Planes,2,1,FS);
 fwrite(&BPP,2,1,FS);

 fwrite(&Compression,4,1,FS);

 fwrite(&ImageSize,4,1,FS);
 fwrite(&ResX,4,1,FS);
 fwrite(&Resy,4,1,FS);

 fwrite(&ColorUsed,4,1,FS);
 fwrite(&ColorImportant,4,1,FS);
}

void Save(Picture Pic)
{
 for(int Y=Pic.iHeight;Y>0;Y--)
 {
  for(int X=0;X<Pic.iWidth;X++)
  {
   fwrite(&(Pic.ImgArray[X,Y].Blue),1,1,Pic.FS);
   fwrite(&(Pic.ImgArray[X,Y].Green),1,1,Pic.FS);
   fwrite(&(Pic.ImgArray[X,Y].Red),1,1,Pic.FS);
  }
 }

}

void WritePixel(Picture Pic,int X,int Y,Color PixelColor)
{
 Pic.ImgArray[X,Y] = PixelColor;
}

Color GetColor(unsigned char Red,unsigned unsigned Green,unsigned unsigned Blue)
{
 Color TmpColor;

 TmpColor.Red = Red;
 TmpColor.Green = Green;
 TmpColor.Blue = Blue;

 return TmpColor;
}
void Close(Picture Pic)
{
 fclose(Pic.FS); 
}



Pour l'utiliser :


#include "stdafx.h"
#include "BitmapWriterLib.h"

int main(int argc, char* argv[])
{
 Picture MyPic= BuildPicture("\\\\galileo\\gaudin.m\\Mes documents\\TestFile.bmp",800,600);
 

 for(int X=0;X<MyPic.iWidth;X++)
 {
  for(int Y=0;Y<MyPic.iHeight;Y++)
  {
   WritePixel(MyPic,X,Y,GetColor(255,255,255));
  }
 }

 WritePixel(MyPic,400,300,GetColor(255,0,0));

 Save(MyPic);
 Close(MyPic);

 return 0;
}



MLerci d'avance !
Tchou !
-=Ar$£nik=-

mardi 4 décembre 2007 à 11:49:01 | Re : Ecriture d'un fichier BMP "à l'ancienne"

Pistol_Pete

Salut

Dans ta fonction  GetColor, tu retourne une variable local, tu ne peux donc pas etre sur que ta variable en sorti de fonction est correcte.
Je ne sais pas si ton problème vient de là, mais c'est important à corriger.

A+
Mon site internet : [ Lien ]


mardi 4 décembre 2007 à 13:16:39 | Re : Ecriture d'un fichier BMP "à l'ancienne"

Pistol_Pete

Re
Ya quand meme pas mal de chose à revoir:
L'allocation dynamique de  TmpPic.ImgArray n'est pas correct : Tu alloues
(sizeof(Color)*iWidth) + (sizeof(Color)*iHeight) pour une image 600 par 800 ca fait un tableau de 1400 places alors qu'il y a 480 000 pixels !!!
L'accès à ton tableau est aussi incorrecte Pic.ImgArray[X,Y] jamais vu cette syntaxe, j'arrive meme pas à comprendre pourquoi ca compile sans erreur.
Pour accéder au pixel X,Y, il faut un truc du genre: [X+Y*Width]

Je pense que faire une classe serait plus simple ici.

A+
Mon site internet : [ Lien ]


mardi 4 décembre 2007 à 13:28:29 | Re : Ecriture d'un fichier BMP "à l'ancienne"

Pistol_Pete

Voila une version qui marche:

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

using namespace std;

// Structs
typedef struct{
 unsigned char Red;
 unsigned char Green;
 unsigned char Blue;
}Color;

typedef struct
{
 Color* ImgArray;

 char* Filename;
 int iWidth;
 int iHeight;

 FILE* FS;
}Picture;

void InitBmpFile(FILE *FS,unsigned int iWidth,unsigned int iHeight);

Picture BuildPicture(char* Filename,unsigned int iWidth,unsigned int iHeight)
{
 Picture TmpPic;

 TmpPic.Filename = Filename;
 TmpPic.FS = fopen(Filename,"wb");

 TmpPic.iWidth = iWidth;
 TmpPic.iHeight = iHeight;

 TmpPic.ImgArray = (Color*)malloc((sizeof(Color)*iWidth * iHeight));
 
 InitBmpFile(TmpPic.FS,iWidth,iHeight);

 return TmpPic;
}

void InitBmpFile(FILE *FS,unsigned int iWidth,unsigned int iHeight)
{
 const char *BMFormat = "BM";
 unsigned int BMPHeaderLenght = (iWidth*iHeight*3) + 54;
 unsigned int ReservedBit = 0;
 unsigned int DataOffset = 54;

 unsigned int DataHeaderLenght = 40;
 unsigned short Planes = 1;
 unsigned short BPP = 24;

 unsigned int Compression = 0;

 unsigned int ImageSize = 0;//(iWidth*iHeight*3);

 unsigned int ResX = 0;
 unsigned int Resy = 0;

 unsigned int ColorUsed =0;
 unsigned int ColorImportant = 0;

 fwrite(BMFormat,1,2,FS);
 fwrite(&BMPHeaderLenght,4,1,FS);
 fwrite(&ReservedBit,4,1,FS);
 fwrite(&DataOffset,4,1,FS);
 
 fwrite(&DataHeaderLenght,4,1,FS);
 fwrite(&iWidth,4,1,FS);
 fwrite(&iHeight,4,1,FS);

 fwrite(&Planes,2,1,FS);
 fwrite(&BPP,2,1,FS);

 fwrite(&Compression,4,1,FS);

 fwrite(&ImageSize,4,1,FS);
 fwrite(&ResX,4,1,FS);
 fwrite(&Resy,4,1,FS);

 fwrite(&ColorUsed,4,1,FS);
 fwrite(&ColorImportant,4,1,FS);
}

void Save(Picture Pic)
{
   
 for(int Y=Pic.iHeight-1;Y>=0;Y--)
 {
  for(int X=0;X<Pic.iWidth;X++)
  {
    fwrite(&(Pic.ImgArray[X+Pic.iWidth*Y].Blue),1,1,Pic.FS);
    fwrite(&(Pic.ImgArray[X+Pic.iWidth*Y].Green),1,1,Pic.FS);
    fwrite(&(Pic.ImgArray[X+Pic.iWidth*Y].Red),1,1,Pic.FS);
  }
 }

}

void WritePixel(Picture Pic,int X,int Y,Color PixelColor)
{
    Pic.ImgArray[X+Pic.iWidth*Y].Red = PixelColor.Red;
    Pic.ImgArray[X+Pic.iWidth*Y].Green = PixelColor.Green;
    Pic.ImgArray[X+Pic.iWidth*Y].Blue = PixelColor.Blue;
}

Color GetColor(unsigned char Red,unsigned unsigned Green,unsigned unsigned Blue)
{
 Color TmpColor;

 TmpColor.Red = Red;
 TmpColor.Green = Green;
 TmpColor.Blue = Blue;

 return TmpColor;
}
void Close(Picture Pic)
{
 fclose(Pic.FS);
}





int main(int argc, char* argv[])
{
 Picture MyPic= BuildPicture("TestFile.bmp",800,600);
 Color tt;
 tt.Blue=0;
 tt.Green=0;
 tt.Red=0;

  Color tt2;
 tt2.Blue=0;
 tt2.Green=255;
 tt2.Red=255;
 for(int X=0;X<MyPic.iWidth;X++)
  for(int Y=0;Y<MyPic.iHeight;Y++)
      WritePixel(MyPic,X,Y,tt);
 
 
 //Ecrire 2 pixels jaune
 WritePixel(MyPic,1,1,tt2);
 WritePixel(MyPic,400,300,tt2);

 Save(MyPic);
 Close(MyPic);

 return 0;
}

A+
Mon site internet : [ Lien ]


mardi 4 décembre 2007 à 17:44:31 | Re : Ecriture d'un fichier BMP "à l'ancienne"

juju12

Pas regardé en détail mais il me semble que vous oubliez un truc : dans le codage bitmap chaque rangée doit être un multiple de 4 octets, peu importe la résolution en couleur. Dans le cas du test (800*600) c'est OK puisque 800 divisible par 4, par contre pour une image quelconque (essayez 799*600 par exemple ca devrait pas marcher) faut compléter chaque ligne avec des zéros.

mercredi 5 décembre 2007 à 10:46:48 | Re : Ecriture d'un fichier BMP "à l'ancienne"

Pistol_Pete

Oui tu as tout à faire raison Juju, on ne peut pas faire des images quelconques avec cet algo.

A+
Mon site internet : [ Lien ]


mercredi 5 décembre 2007 à 18:14:10 | Re : Ecriture d'un fichier BMP "à l'ancienne"

MaxSoldier

Membre Club
Salut à tous ! Tout d'abord, merci pour toutes ces réponses ! Je vais essayer de vous répondre un par un en expliquant le pourquoi du comment :-p

Pistol_Pete : Je débute en programmation C++, je viens du C# d'ou une structure de code peut être un peu étrange, j'ai appris sur le tas, au fil des erreur de compilation... Je vais essayé de corriger ça

Juju : Je sais mais ce programme étant quasiment un programme de test, j'ai essayé de pas trop me compliqué la vie pour les 0 à la fin d'une ligne non divisible par 4. Quant au 4 composante, j'ai lu partout qu'il n'en fallait que 3, dans l'ordre, bleu vert rouge ( Little-endien)

Merci à tous, je vais pouvoir avancer grâce à vous !
-=Ar$£nik=-



Cette discussion est classé dans : int, fs, unsigned, fwrite, iheight


Répondre à ce message

Sujets en rapport avec ce message

Hexadécimal HELP ! [ par Xentor ] Bonjour,Mon problème est le suivant : je vient d'effectuer un AND sur une variable, et celle ci, bien que conservant son type unsigned int se met en h conversion constante en hexa ->unsigned long ou int ??? [ par andrealphus ] 4ndr&@lphu$rebonjour à tous et toutes,mon nouveau probleme est ridicule mais gênant...comment peut on convertir un nombre hexadécimal (du style l'adre Fch. Header :: CONIO.H [ par TontOnDuWeb ] Pour ce que ca interesse (avec vc++ les fonctions suivantes e sont pas incluse (du moins je crois...))>>#if !defined(__CONIO_H)#define __CONIO_H#if !d pb de retour( du tableau) de ma fonction [ par airwann ] bonjour,j ai un problème comment dois je modifier l'entête de ma fonction pour recupérer le tableau de structure 3 d alloué dynamiquementmerci d avanc transformer un tableau 2d en image bitmap [ par gyzmo1 ] Bonjour a tous, voilà mon problème, je suis en train de mettre en place une méthode de comparaison de signature manuscrites. Cette méthode s applique class matrice [ par flaky ] Slt à tousJ'utilise une classe "matrice" (celle de nicolas aunai, téléchargée sur le site) qui fonctionne très bien. Mais j'ai du mal à manipuler l'ob Segmentation Fault....en traitement d'image [ par psysta ] Bonjour,je suis nouveau dans la programmation en C. J'ai un programme Matlab qui marche bien, et je souhaiterais l'implémenter en C. Le pgm compile bi PB DIALOGBOX (Win32) [ par moustachu ] Bonjour,Je dois recréer des projets VC++6.0 à partir des fichiers dont je dispose. Le problème se pose avec un fichier chgmod.rc. J'arrive bien à l'ou comment afficher un pixel en VGA ? [ par LedPaL ] Slt,je programme ac dev-cpp et j'arrive pas a afficher de pixels a l'écran !!! de l'aide plz !!voici un bout de ma source:unsigned char * ecran = (uns


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,374 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.