Accueil > > > CONVERTIR UNE IMAGE 16 MILLIONS DE COULEURS EN NIVEAUX DE GRIS [BORLAND C++]
CONVERTIR UNE IMAGE 16 MILLIONS DE COULEURS EN NIVEAUX DE GRIS [BORLAND C++]
Information sur la source
Description
La convertion en niveau de gris est tres importante lorsque l'on veut faire du traitement d'image.
Ce code permet de convertir un fichier bitmap de 16 millions de couleurs en niveaux de gris. En 16 millions de couleurs un pixel est codé par trois octets(bleu, vert ,rouge). Pour convertir en niveaux de gris on additionne ces trois valeurs est on les divise par trois.
Pour les images couleurs ayant jusqu a 256 couleurs, l'algo est plus simple car il suffit de modifier la palette de couleurs. Je n ai pas integrer cette fonction pour le moment.
voila comment se deroule le programme
-Lecture de l'en-tete de l image 16 millions de couleurs
-Modification de l'en-tete pour obtenir un en-tete d'un fichier de 256 couleurs
-Création de la platte en niveaux de gris
-reconstruire l'image en niveaux de gris avec le calcul expliqué plus haut
Source
- /*********************************************************************
- nom: conv_nb
- programmé par Draven
- le 18/06/2003
- **********************************************************************/
-
- #include <stdio.h> /* printf(), scanf, fopen() ... */
- #include <stdlib.h> /* exit() */
- #include <windows.h> /*BITMAPFILEHEADER et BITMAPINFOHEADER */
-
- /* structure comprenant les 2 en-têtes du fichier bitmap (54 octets) */
- typedef struct
- {
- BITMAPFILEHEADER file; /*information sur le fichier (ex type,taille du fichier ) */
- BITMAPINFOHEADER info; /*information sur la données de l'image (ex nbrcouleur utilise, longueur,largeur, taille de l'image) */
- }HEADER;
-
- typedef struct
- {
- BYTE bleu;
- BYTE vert;
- BYTE rouge;
- }PIXEL;
-
- HEADER en_tete(FILE*,HEADER,char *);
- void changer(FILE*,HEADER);
- void traitement(FILE *,FILE *, HEADER);
-
- void main()
- {
- char nom_fichier[50];
- FILE *source;
- FILE *destination;
- HEADER header;
-
- printf("Entrez le nom du fichier: ");
- scanf("%s",nom_fichier);
- if((source=fopen(nom_fichier,"rb"))==NULL)
- {
- printf("erreur à l'ouverture du fichier\n");
- exit(-1);
- }
- /* créer un fichier temporaire pour recopier une partie du fichier source*/
- if((destination=fopen("tempo.bmp","wb"))==NULL)
- {
- printf("erreur à l'ouverture du fichier\n");
- exit(-1);
- }
- header=en_tete(source,header,nom_fichier);
- changer(destination,header);
- traitement(source,destination, header);
- printf("FIN");
- fclose(source);
- fclose(destination);
-
- remove(nom_fichier); /* supprimer le fichier source */
- rename("tempo.bmp",nom_fichier); /*renommer le fichier temporaire avec le nom du fichier source */
- }
- /*********************************************************************
- nom: en_tete
- role: lire l'en-tete du fichier bitmap passé en parametre
- **********************************************************************/
- HEADER en_tete(FILE* fd,HEADER header,char *nom_fichier)
- {
- fread(&header,sizeof(HEADER),1,fd); /* lire les 54 premiers octets qui constitue l'en-tete */
- /* tester si les 2 premiers octets sont B et M */
- if(header.file.bfType!=0x4D42)
- {
- printf("%s n'est pas un fichier bitmap\n",nom_fichier);
- fclose(fd);
- exit(-1);
- }
- /* on teste si l'image est en 16 millions de couleurs */
- if(header.info.biBitCount!=24 || header.info.biBitCount!=0)
- {
- printf("Le fichier %s n'est pas en 16 millions de couleurs\n",nom_fichier);
- fclose(fd);
- exit(-1);
- }
- return header;
- }
-
- /******************************************************************
- nom: changer
- role: transforme l'en-tete pour un fichier image de 256 couleurs
- et créer la palette de niveaux de gris.
- L'en-tête modifié et la palette seront envoyé dans un nouveau fichier vide.
- *******************************************************************/
- void changer(FILE* destination,HEADER header)
- {
- int i;
- RGBQUAD palette; /* description d'un pixel. composé d'une valeur bleu, vert, rouge, et de bourrage */
- /*modification de l'en-tête*/
- header.info.biBitCount=8; /* utilisation de 256 couleurs */
- header.info.biClrUsed=256; /* nbr de couleurs utilisé (256)*/
- header.info.biClrImportant=256;
- /* copie de l'entete bmp (54 premiers octets) de le fichier "tempo.bmp" */
- fwrite(&header,sizeof(HEADER),1,destination);
-
- /* création de la palette en niveau de gris*/
- for(i=0;i<256;i++)
- {
- /* la palette se compose d'une composante bleue, verte, rouge, et d'un octet de bourrage*/
- palette.rgbBlue=i;
- palette.rgbGreen=i;
- palette.rgbRed=i;
- palette.rgbReserved=0x00;
- /* écrire les quatre octets composant la couleur dans le fichier */
- fwrite(&palette,sizeof(RGBQUAD),1,destination);
- }
- }
-
- /*********************************************************************
- nom: traitement
- role: reconstitue l'image couleurs en niveaux de gris
- **********************************************************************/
- void traitement(FILE *source ,FILE *destination, HEADER header)
- {
- int longueur,longueur32,bourrage;
- int longueur32_nb,bourrage_nb;
- int cpt,i;
- int nouveau_pixel;
- int tempo;
- PIXEL pixel;
- longueur=header.info.biWidth;
- /* la largeur d'une image doit être un multiple de 4 (32 bits)
- si ce n'est pas le cas des bourrage de 0 seront inserer a la fin */
-
- /* Ici on calcule le nombre de bourrage pour chaque largeur de l'image en 16 millions de couleurs*/
- /* pour le format 16 millions de couleurs*/
- longueur32=longueur*3;
- while((longueur32%4)!=0)
- longueur32++;
- bourrage=longueur32-(longueur*3);
-
- /* Ici on calcule le nombre de bourrage pour chaque largeur de l'image en 256 couleurs*/
- /* pour le format 256 couleurs*/
- longueur32_nb=longueur;
- while((longueur32_nb%4)!=0)
- longueur32_nb++;
- bourrage_nb=longueur32_nb-longueur;
-
- /* se positionner au debut de la données de l'image pour l'image de 16 millions de couleurs */
- fseek(source,0x36,SEEK_SET);
- /* se positionner en fin de fichier, c'est à dire juste après la palette */
- fseek(destination,0x00,SEEK_END);
-
- /* faire autant de fois que la hauteur de l'image*/
- for(cpt=0;cpt<header.info.biHeight;cpt++)
- {
- /* faire cette boucle pour chaque pixel de la largeur de l'image */
- for(i=0;i<longueur;i++)
- {
- /* lire trois octets dans le fichier source qui correspondent aux composantes bleue, verte et rouge*/
- fread(&pixel,sizeof(pixel),1,source);
- /* on additionne la valeur des 3 composantes du pixel que l on divise par trois pour obtenir la valeur en niveau de gris */
- nouveau_pixel=(pixel.bleu+pixel.vert+pixel.rouge)/3;
- /* ecrire la nouvelle valeur du pixel dans le fichier source*/
- /* pour une image en 256 couleurs 1 octet suffit pour coder un pixel*/
- fputc(nouveau_pixel,destination);
- }
- /* avancer du nombre de bit de bourrage de l'image en 16 millions de couleurs*/
- fseek(source,bourrage,SEEK_CUR);
-
- /* ecrire le nombre de bourrage nécessaire dans l'image de 256 couleurs*/
- for(i=0;i<bourrage_nb;i++)
- fputc(0x00,destination);
- }
- }
/*********************************************************************
nom: conv_nb
programmé par Draven
le 18/06/2003
**********************************************************************/
#include <stdio.h> /* printf(), scanf, fopen() ... */
#include <stdlib.h> /* exit() */
#include <windows.h> /*BITMAPFILEHEADER et BITMAPINFOHEADER */
/* structure comprenant les 2 en-têtes du fichier bitmap (54 octets) */
typedef struct
{
BITMAPFILEHEADER file; /*information sur le fichier (ex type,taille du fichier ) */
BITMAPINFOHEADER info; /*information sur la données de l'image (ex nbrcouleur utilise, longueur,largeur, taille de l'image) */
}HEADER;
typedef struct
{
BYTE bleu;
BYTE vert;
BYTE rouge;
}PIXEL;
HEADER en_tete(FILE*,HEADER,char *);
void changer(FILE*,HEADER);
void traitement(FILE *,FILE *, HEADER);
void main()
{
char nom_fichier[50];
FILE *source;
FILE *destination;
HEADER header;
printf("Entrez le nom du fichier: ");
scanf("%s",nom_fichier);
if((source=fopen(nom_fichier,"rb"))==NULL)
{
printf("erreur à l'ouverture du fichier\n");
exit(-1);
}
/* créer un fichier temporaire pour recopier une partie du fichier source*/
if((destination=fopen("tempo.bmp","wb"))==NULL)
{
printf("erreur à l'ouverture du fichier\n");
exit(-1);
}
header=en_tete(source,header,nom_fichier);
changer(destination,header);
traitement(source,destination, header);
printf("FIN");
fclose(source);
fclose(destination);
remove(nom_fichier); /* supprimer le fichier source */
rename("tempo.bmp",nom_fichier); /*renommer le fichier temporaire avec le nom du fichier source */
}
/*********************************************************************
nom: en_tete
role: lire l'en-tete du fichier bitmap passé en parametre
**********************************************************************/
HEADER en_tete(FILE* fd,HEADER header,char *nom_fichier)
{
fread(&header,sizeof(HEADER),1,fd); /* lire les 54 premiers octets qui constitue l'en-tete */
/* tester si les 2 premiers octets sont B et M */
if(header.file.bfType!=0x4D42)
{
printf("%s n'est pas un fichier bitmap\n",nom_fichier);
fclose(fd);
exit(-1);
}
/* on teste si l'image est en 16 millions de couleurs */
if(header.info.biBitCount!=24 || header.info.biBitCount!=0)
{
printf("Le fichier %s n'est pas en 16 millions de couleurs\n",nom_fichier);
fclose(fd);
exit(-1);
}
return header;
}
/******************************************************************
nom: changer
role: transforme l'en-tete pour un fichier image de 256 couleurs
et créer la palette de niveaux de gris.
L'en-tête modifié et la palette seront envoyé dans un nouveau fichier vide.
*******************************************************************/
void changer(FILE* destination,HEADER header)
{
int i;
RGBQUAD palette; /* description d'un pixel. composé d'une valeur bleu, vert, rouge, et de bourrage */
/*modification de l'en-tête*/
header.info.biBitCount=8; /* utilisation de 256 couleurs */
header.info.biClrUsed=256; /* nbr de couleurs utilisé (256)*/
header.info.biClrImportant=256;
/* copie de l'entete bmp (54 premiers octets) de le fichier "tempo.bmp" */
fwrite(&header,sizeof(HEADER),1,destination);
/* création de la palette en niveau de gris*/
for(i=0;i<256;i++)
{
/* la palette se compose d'une composante bleue, verte, rouge, et d'un octet de bourrage*/
palette.rgbBlue=i;
palette.rgbGreen=i;
palette.rgbRed=i;
palette.rgbReserved=0x00;
/* écrire les quatre octets composant la couleur dans le fichier */
fwrite(&palette,sizeof(RGBQUAD),1,destination);
}
}
/*********************************************************************
nom: traitement
role: reconstitue l'image couleurs en niveaux de gris
**********************************************************************/
void traitement(FILE *source ,FILE *destination, HEADER header)
{
int longueur,longueur32,bourrage;
int longueur32_nb,bourrage_nb;
int cpt,i;
int nouveau_pixel;
int tempo;
PIXEL pixel;
longueur=header.info.biWidth;
/* la largeur d'une image doit être un multiple de 4 (32 bits)
si ce n'est pas le cas des bourrage de 0 seront inserer a la fin */
/* Ici on calcule le nombre de bourrage pour chaque largeur de l'image en 16 millions de couleurs*/
/* pour le format 16 millions de couleurs*/
longueur32=longueur*3;
while((longueur32%4)!=0)
longueur32++;
bourrage=longueur32-(longueur*3);
/* Ici on calcule le nombre de bourrage pour chaque largeur de l'image en 256 couleurs*/
/* pour le format 256 couleurs*/
longueur32_nb=longueur;
while((longueur32_nb%4)!=0)
longueur32_nb++;
bourrage_nb=longueur32_nb-longueur;
/* se positionner au debut de la données de l'image pour l'image de 16 millions de couleurs */
fseek(source,0x36,SEEK_SET);
/* se positionner en fin de fichier, c'est à dire juste après la palette */
fseek(destination,0x00,SEEK_END);
/* faire autant de fois que la hauteur de l'image*/
for(cpt=0;cpt<header.info.biHeight;cpt++)
{
/* faire cette boucle pour chaque pixel de la largeur de l'image */
for(i=0;i<longueur;i++)
{
/* lire trois octets dans le fichier source qui correspondent aux composantes bleue, verte et rouge*/
fread(&pixel,sizeof(pixel),1,source);
/* on additionne la valeur des 3 composantes du pixel que l on divise par trois pour obtenir la valeur en niveau de gris */
nouveau_pixel=(pixel.bleu+pixel.vert+pixel.rouge)/3;
/* ecrire la nouvelle valeur du pixel dans le fichier source*/
/* pour une image en 256 couleurs 1 octet suffit pour coder un pixel*/
fputc(nouveau_pixel,destination);
}
/* avancer du nombre de bit de bourrage de l'image en 16 millions de couleurs*/
fseek(source,bourrage,SEEK_CUR);
/* ecrire le nombre de bourrage nécessaire dans l'image de 256 couleurs*/
for(i=0;i<bourrage_nb;i++)
fputc(0x00,destination);
}
}
Conclusion
Petit bug: Avec paint l'image en niveau de gris est parfaite, mais dès que je la passe sur un logiciel de retouche d'image l'image se decale. Si quelqu un pouvait m'aider à rectifier se bug ca serait sympa.
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
Derniers Blogs
[FRAMEWORK 4] LES TASKS ET LE THREAD UI[FRAMEWORK 4] LES TASKS ET LE THREAD UI par fathi
Je viens de passer quelques temps au TechDay's et j'ai pu voir pas mal de session intéressante. Par contre une chose m'a un peu étonné lors de certaines de ces sessions qui abordaient les améliorations du framework .NET (donc le 4.5) : en gros, bea...
Cliquez pour lire la suite de l'article par fathi WORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBEWORKFLOW FOUNDATION 3 A UN PIED DANS LA TOMBE par JeremyJeanson
Depuis déjà un an, je conseille vivement les utilisateurs de Workflow Foundation 3 à migrer vers la version 4. L'information qui va suivre ne devrait donc pas trop prendre au dépourvu les personnes qui m'ont suivi. Je profite de ce poste, pour faire le re...
Cliquez pour lire la suite de l'article par JeremyJeanson TECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PCTECHDAYS PARIS 2012 : NOUVELLES TENDANCES DU POSTE DE TRAVAIL - BRING YOUR OWN PC par ROMELARD Fabrice
Speakers: Thierry Rapatout, Antoine Petit et Xavier Trebbia Cette session entre dans le cadre des RDV Décideurs des TechDays 2012, elle est liée à la consumérisation de l'IT et la mise en place du "DeskTop as a Service" dans de plus en ...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2012 : SYSTEM CENTER SERVICE MANAGER 2012 VUE D'ENSEMBLETECHDAYS PARIS 2012 : SYSTEM CENTER SERVICE MANAGER 2012 VUE D'ENSEMBLE par ROMELARD Fabrice
Speakers: Julien Marechal, Gautier Confiant, Sébastien MEYER La session débute par le positionnement de la solution System Center par rapport aux concepts d'organisation ITIL. Le portail du catalogue de se...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2012 : PLEINIèRE SECOND JOURTECHDAYS PARIS 2012 : PLEINIèRE SECOND JOUR par ROMELARD Fabrice
Après une première journée dédiée aux développeurs, cette seconde journée est dédiée au monde des entreprises et de ses applications. Ainsi, cette pleinière est dédiée à faire un 360 de l'évolution des applications Business aux demandes ac...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning COLLECTOR PLUS (3.00B)COLLECTOR PLUS (3.00B)COLLECTOR PLUS version 3.00B est un logiciel utilisant une base de données alimentée par :
- L... Cliquez pour télécharger COLLECTOR PLUS PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO LettresFaciles 2011 (8.0.0.1)LETTRESFACILES 2011 (8.0.0.1)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011
|