Lire et écrire des fichiers image PPM

Lire et écrire nativement des fichiers image PPM

Voir version :

Pas de dépendances

Télécharger :

Plusieurs fichiers :
01_09_01_testppm.c
01_09_01_quickimage.h
01_09_01_quickimage.c


01_09_01_testppm.c

#include "01_09_01_quickimage.h" int main() { int i,j; Image* I = NouvelleImage(256,256); for(i=0;i<256;i++) { for(j=0;j<256;j++) { Pixel p; p.r = i; p.g = j; p.b = 0; SetPixel(I,i,j,p); } } //Image* I = Charger("test.ppm"); Sauver(I,"test.ppm"); DelImage(I); return 0; }


01_09_01_quickimage.h

#ifndef _QUICKIMAGE_H #define _QUICKIMAGE_H typedef struct Pixel { unsigned char r,g,b; } Pixel; typedef struct Image { int w,h; Pixel* dat; } Image; Image* Charger(const char* fichier); int Sauver(Image*,const char* fichier); Image* NouvelleImage(int w,int h); Image* CopieImage(Image*); void SetPixel(Image*,int i,int j,Pixel p); Pixel GetPixel(Image*,int i,int j); void DelImage(Image*); #endif


01_09_01_quickimage.c

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include "01_09_01_quickimage.h" Image* NouvelleImage(int w,int h) { Image* I = malloc(sizeof(Image)); I->w = w; I->h = h; I->dat = calloc(1,w*h*sizeof(Pixel*)); return I; } Image* CopieImage(Image* I) { Image* res; if (!I) return NULL; res = NouvelleImage(I->w,I->h); memcpy(res->dat,I->dat,I->w*I->h*sizeof(Pixel)); return res; } void DelImage(Image* I) { if (I) { free(I->dat); free(I); } } void SetPixel(Image* I,int i,int j,Pixel p) { assert(I && i>=0 && i<I->w && j>=0 && j<I->h); I->dat[I->w*j+i] = p; } Pixel GetPixel(Image* I,int i,int j) { assert(I && i>=0 && i<I->w && j>=0 && j<I->h); return I->dat[I->w*j+i]; } Image* Charger(const char* fichier) { int i,j,max; char buf[10]; Image* I; FILE* F = fopen(fichier,"r"); if (!F) return NULL; fscanf(F,"%s %d %d %d",buf,&i,&j,&max); I = NouvelleImage(i,j); for(i=0;i<I->w*I->h;i++) { int r,g,b; fscanf(F,"%d %d %d",&r,&g,&b); I->dat[i].r = (unsigned char)r; I->dat[i].g = (unsigned char)g; I->dat[i].b = (unsigned char)b; } fclose(F); return I; } int Sauver(Image* I,const char* fichier) { int i; FILE* F = fopen(fichier,"w"); if (!F) return -1; fprintf(F,"P3\n%d %d\n255\n",I->w,I->h); for(i=0;i<I->w*I->h;i++) fprintf(F,"%d %d %d ",I->dat[i].r,I->dat[i].g,I->dat[i].b); fclose(F); return 0; }


Commentaires

	Voici un exemple pour écrire et lire des fichiers PPM sans utiliser de librairies externes.
	Les fichiers PPM sont des formats d'image très simple à lire et écrire.

	Ils se relisent avec toute sorte de logiciels de dessin (cependant, Windows (avec Paint), ne les remonte pas nativement)
	Vous pouvez utiliser ACDSEE, ou bien XnView, ou tout autre logiciel de dessin.

	Le programme est simple :

// Regardez le .h

	On a une structure Pixel.

	Un pixel, c'est 3 couleurs : rouge, vert, bleu, qui varient de 0 à 255 chacun. 
	Avec ça, vous pouvez faire toutes les couleurs possible.

	Nous avons également une structure Image, qui contient une taille (largeur w et hauteut h) (de l'anglais width et height)
	et un tableau de pixels.

	Voila comment on définit une image en mémoire.

	Les fonctions que j'ai fait avec :

	Une fonction NouvelleImage : vous lui donnez une taille, elle construit la structure
	Une fonction DelImage : qui détruit, désalloue une image
	Une fonction CopieImage : qui recopie une image

	Vous n'aurez aucun malloc à faire dans votre main pour manipuler le tout.

	Une fonction GetPixel, et une autre SetPixel : vous leur donnez l'image, les coordonnées i,j du pixel voulu, et hop, 
	elles lisent/écrivent le pixel en mémoire.

	Charger et Sauver, qui chargent et sauvent une image PPM. 

// Regardez le main

	Une utilisation très simple du tout : on crée une image de 255*255 pixels, on fait un double for, 
	et on fait varier le rouge sur l'axe x, et le vert sur l'axe y.

	On sauve le tout : regardez le résultat dans votre répertoire avec un logiciel de dessin : l'image est un beau dégradé.

// Le format PPM

	Le format PPM est simple :
	C'est un format Texte. Vous écrivez d'abord le header P3, puis les dimensions de l'image, suivi du nombre maximal (chez nous 255)

	Puis tous les pixels les uns après les autres.
	Explication supplémentaire :
	http://fr.wikipedia.org/wiki/Portable_pixmap#Fichier_ASCII_3

	Vous remarquerez sur cette page qu'on peut aussi écrire des fichiers PPM binaires, 
	mais aussi des PBM (noir et blanc : juste noir OU blanc), et PGM (nuances de gris) tout aussi simples à écrire.