1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
(* La taille qui nous intéresse. *)
let pixels_h = 600
let pixels_w = 800
(* La fonction (int -> int -> color -> unit) -> color array array -> unit
* Elle est en fait plus générale que ça... mais c'est son utilisation ici. *)
let apply f = Array.iteri (fun x -> Array.iteri (f x))
(* La fonction de transformation. *)
let grayscale x y c =
(* Une couleur est donnée sous la forme 0xRRGGBB. On récupère ici les
* composantes avec des opérations bit-à-bit (pas indispensable). *)
let r = (c lsr 16) land 255 and g = (c lsr 8) land 255 and b = c land 255 in
let mean = (r + g + b) / 3 in
Graphics.set_color (mean lsl 16 + mean lsl 8 + mean);
Graphics.plot y x
(* Crée une image. Cette fonction est (de toute évidence) assez lente.
* On crée la matrice par la même occasion. *)
let build_image () =
let tbl = Array.init pixels_h (fun y ->
Array.init pixels_w (fun x ->
let clr = Graphics.rgb x (x * y) y in
Graphics.set_color clr;
Graphics.plot x y;
clr
)) in
(* Mise à jour des tracés, en une seule fois. *)
Graphics.synchronize ();
tbl
let _ =
(* Créons une nouvelle fenêtre graphique. *)
Graphics.open_graph "";
(* Pas de synchronisation automatique entre le buffer en arrière-plan et la
* fenêtre, pour gagner un peu en vitesse d'exécution. *)
Graphics.auto_synchronize false;
(* Dessinons une image, dont on récupère la matrice. *)
let tbl = build_image () in
(* Attendre une action avant de continuer. *)
ignore (Graphics.wait_next_event [Graphics.Button_down]);
apply grayscale tbl;
Graphics.synchronize ();
(* Attendre une action pour quitter... *)
ignore (Graphics.wait_next_event [Graphics.Button_down]) |
Partager