171 lines
4.4 KiB
OCaml
171 lines
4.4 KiB
OCaml
(*
|
|
auteur : FIL
|
|
date : janvier 2010
|
|
objet : lecture et sauvegarde de fichiers image dans différents format
|
|
(PGM, PPM, JPG, PNG, GIF, ...)
|
|
necessite l'installation de la commande convert de la suite de traitements
|
|
d'images Image Magick (http://www.imagemagick.org/)
|
|
*)
|
|
|
|
|
|
|
|
let suffixe_tmp = ".tmp "
|
|
and rm =
|
|
if Sys.os_type="Unix" then
|
|
"rm -f "
|
|
else
|
|
"del "
|
|
and mv =
|
|
if Sys.os_type="Unix" then
|
|
"mv "
|
|
else
|
|
"move "
|
|
and dev_null =
|
|
if Sys.os_type="Unix" then
|
|
" 2> /dev/null"
|
|
else
|
|
""
|
|
|
|
|
|
open Graphics
|
|
|
|
(*
|
|
fonction
|
|
lire_image_ppm : string -> color array array
|
|
parametre
|
|
nom : string = nom du fichier pgm ou ppm
|
|
* valeur renvoyee : color array array = tableau des pixels
|
|
CU :
|
|
- suppose qu'un fichier nommé nom contenant une image au format pgm existe
|
|
- n'accepte pas de ligne de commentaire (commencant par #) dans l'entete du fichier
|
|
*)
|
|
let lire_image_ppm nom =
|
|
let entree = open_in_bin nom
|
|
in
|
|
let format = input_line entree
|
|
and largeur,hauteur =
|
|
let ligne = ref (input_line entree)
|
|
in
|
|
while !ligne.[0] = '#' do
|
|
ligne := input_line entree
|
|
done ;
|
|
Scanf.sscanf
|
|
!ligne
|
|
"%d %d"
|
|
(fun x y -> x,y)
|
|
and _ = input_line entree (* lecture de la ligne contenant 255 *)
|
|
in
|
|
let img = Array.make_matrix hauteur largeur (rgb 0 0 0)
|
|
and en_couleur = (format = "P6")
|
|
in
|
|
for i = 0 to hauteur - 1 do
|
|
for j = 0 to largeur - 1 do
|
|
img.(i).(j) <-
|
|
if en_couleur then
|
|
let x = input_byte entree
|
|
and y = input_byte entree
|
|
and z = input_byte entree
|
|
in
|
|
rgb x y z
|
|
else
|
|
let x = input_byte entree
|
|
in
|
|
rgb x x x
|
|
done
|
|
done ;
|
|
close_in entree ;
|
|
img
|
|
|
|
|
|
(*
|
|
fonction lire_image : string -> color array array
|
|
parametre
|
|
nom : string = nom du fichier image a lire
|
|
valeur renvoyee : color array array = tableau des pixels de
|
|
l'image contenue dans le fichier
|
|
CU : nom doit etre un fichier image d'un format courant
|
|
(ie connu de l'utilitaire convert de la suite ImageMagick)
|
|
|
|
*)
|
|
let lire_image nom =
|
|
let r = Sys.command ("convert -depth 8 "^nom^" "^nom^".ppm "^dev_null)
|
|
in
|
|
if r <> 0 then
|
|
failwith ("lire_image : fichier "^nom^" manquant ou pas dans un format image")
|
|
else
|
|
let res = lire_image_ppm (nom^".ppm")
|
|
in
|
|
ignore(Sys.command (rm^nom^".ppm"));
|
|
res
|
|
|
|
|
|
(*
|
|
procedure
|
|
dessiner_image : color array array -> unit
|
|
parametre
|
|
img : color array array = image a dessiner
|
|
action : dessine l'image dans le coin inferieur gauche
|
|
CU : une fenetre graphique doit prealablement etre ouverte
|
|
*)
|
|
let dessiner_image img =
|
|
draw_image (make_image img) 0 0
|
|
|
|
|
|
(*
|
|
procedure
|
|
sauver_image_pgm : color array array -> string -> unit
|
|
parametres
|
|
img : color array array = image a sauvegarder
|
|
nom : string = nom du fichier de sauvegarde de l'image
|
|
action : sauvegarde de l'image au format PPM,
|
|
*)
|
|
let sauver_image_ppm (img : Graphics.color array array) nom =
|
|
let sortie = open_out_bin nom
|
|
and hauteur = Array.length img
|
|
and largeur = Array.length img.(0)
|
|
in
|
|
output_string sortie "P6\n" ;
|
|
output_string sortie ((string_of_int largeur)^" "^(string_of_int hauteur)^"\n") ;
|
|
output_string sortie "255\n";
|
|
for i = 0 to hauteur - 1 do
|
|
for j = 0 to largeur - 1 do
|
|
let r = img.(i).(j) / (256*256)
|
|
and g = (img.(i).(j) mod (256*256)) / 256
|
|
and b = img.(i).(j) mod 256
|
|
in
|
|
output_byte sortie r ;
|
|
output_byte sortie g ;
|
|
output_byte sortie b
|
|
done
|
|
done ;
|
|
close_out sortie
|
|
|
|
|
|
let liste_formats = [".png"; ".jpg"; ".gif"; ".bmp"; ".pgm"; ".ppm"]
|
|
|
|
(*
|
|
procedure
|
|
sauver_image : color array array -> string -> unit
|
|
parametres
|
|
img : color array array = image a sauvegarder
|
|
nom : string = nom du fichier de sauvegarde de l'image
|
|
action : sauvegarde de l'image dans un fichier nomme par nom
|
|
CU : le nom du fichier doit se terminer par une extension
|
|
indiquant le format qui doit faire partie de la liste
|
|
liste_formats
|
|
*)
|
|
let sauver_image img nom =
|
|
let suffixe = String.sub nom ((String.length nom) - 4) 4
|
|
in
|
|
if not (List.mem suffixe liste_formats) then
|
|
failwith "sauver_image : format image non reconnu"
|
|
else
|
|
let _ = sauver_image_ppm img (nom^".tmp")
|
|
in
|
|
if suffixe="ppm" then
|
|
ignore(Sys.command (mv^nom^suffixe_tmp^nom))
|
|
else begin
|
|
ignore(Sys.command ("convert "^nom^suffixe_tmp^" "^nom^dev_null)) ;
|
|
ignore(Sys.command (rm^nom^suffixe_tmp))
|
|
end
|