From: Florent Monnier <fmonnier@linux-nantes.fr.eu.org>
To: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Portable PNG exporter
Date: Mon, 22 Sep 2008 16:47:21 +0200 [thread overview]
Message-ID: <200809221647.21886.fmonnier@linux-nantes.fr.eu.org> (raw)
In-Reply-To: <20080920230351.GA9757@annexia.org>
> 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
next prev parent reply other threads:[~2008-09-22 18:49 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-20 17:37 Janne Hellsten
2008-09-20 23:03 ` [Caml-list] " Richard Jones
2008-09-22 14:47 ` Florent Monnier [this message]
2008-09-22 14:59 ` Janne Hellsten
2008-09-22 15:56 ` Daniel Bünzli
2008-09-21 0:47 ` Jon Harrop
2008-09-21 19:50 ` malc
2008-09-21 20:02 ` Janne Hellsten
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200809221647.21886.fmonnier@linux-nantes.fr.eu.org \
--to=fmonnier@linux-nantes.fr.eu.org \
--cc=caml-list@yquem.inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox