Browse thread
Portable PNG exporter
-
Janne Hellsten
-
Richard Jones
- Janne Hellsten
- Florent Monnier
- Jon Harrop
- malc
-
Richard Jones
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Florent Monnier <fmonnier@l...> |
| Subject: | Re: [Caml-list] Portable PNG exporter |
> For reference, I've found the easiest way to export PNGs (in any
> language, not just OCaml) is to use netpbm.
Probably with any language, but perhaps not any OS ?
> Simply fork pnmtopng
> using Unix.open_process_out and write a PPM file. A PPM file has such
> a simple format that you can write it directly from just about any
> language, even a shell script.
>
> P3 <width> <height> 255
> followed by <width>x<height>x3 RGB triplets (in decimal, separated
> by writespace)
You can reduce the amount of exchanged datas using binary ppm instead of ascii
ppm. In such case the format is:
P6\n<width in ascii> <height in ascii>\n255\n
followed by <width>x<height>x3 RGB triplets of octect (in binary)
Here is the OCaml code I use, as well for jpeg:
let output_ppm ~oc ~img:(_, r_channel, g_channel, b_channel) =
let width = Bigarray.Array2.dim1 r_channel
and height = Bigarray.Array2.dim2 r_channel in
Printf.fprintf oc "P6\n%d %d\n255\n" width height;
for y = 0 to pred height do
for x = 0 to pred width do
(* output_byte doesn't raise any exception about the range *)
output_char oc (char_of_int r_channel.{x,y});
output_char oc (char_of_int g_channel.{x,y});
output_char oc (char_of_int b_channel.{x,y});
done;
done;
output_char oc '\n';
flush oc
;;
(* you can use different conversion commands (convert is from ImageMagick) *)
let print_jpeg ~img ?(quality=96) () =
let cmd = Printf.sprintf "cjpeg -quality %d" quality in
(*
let cmd = Printf.sprintf "ppmtojpeg -quality %d" quality in
let cmd = Printf.sprintf "convert ppm:- -quality %d jpg:-" quality in
*)
let ic, oc = Unix.open_process cmd in
output_ppm ~img ~oc;
try
while true do
let c = input_char ic in
print_char c
done
with End_of_file -> ()
;;
(* output any of the hundred formats ImageMagick knows *)
let print_file ~img ~format =
let cmd = Printf.sprintf "convert ppm:- %s:-" format in
let ic, oc = Unix.open_process cmd in
output_ppm ~img ~oc;
try
while true do
let c = input_char ic in
print_char c
done
with End_of_file -> ()
;;
let new_img ~width ~height =
let all_channels =
let kind = Bigarray.int8_unsigned
and layout = Bigarray.c_layout
in
Bigarray.Array3.create kind layout 3 width height
in
let r_channel = Bigarray.Array3.slice_left_2 all_channels 0
and g_channel = Bigarray.Array3.slice_left_2 all_channels 1
and b_channel = Bigarray.Array3.slice_left_2 all_channels 2
in
(all_channels,
r_channel,
g_channel,
b_channel)
;;
_________________________________________
Anyway I'm very pleased to see this png exporter, while it's allways usefull
to remove an external dependency !
Thanks for this piece of code !
--
Florent