How to convert img to pdf from an OCaml program?

What is the simplest and straightest way to turn a png | jpg image in a pdf file with OCaml/an Ocaml binding that can be used with OCaml.4.07.1?
The imagemagick binding would be nice but it requires an older compiler and I can’t downgrade.

Thanks

camlpdf library

Thanks.
I see that there is support for extracting jpg from a pdf. I’ve not found yet how to import a png.
Have you already imported a png in a camldpf object?

You could exec imagemagick instead of using a binding.

Using smth like a Sys command?
It’s a kind of adhoc binding?
But how can I make it safe?

By what meaning of safe?

In my understanding, a binding is supposed to handle all cases to make the use of a external library safe/safest.
Do you mean that I can simply pass the function ‘Sys.command imagemagick foo bar’, and look at the exit code?

You’re the only one who can tell if it fits your needs.

I’d rather use Unix.execv though as there are less quoting worries

Gaëtan Gilbert

/cc @fccm It seems @Luc_ML tried to use your bindings to ImageMagick.

Those can no longer be installed in recent opam universes because of the switch to safe-string by default.

Do you maybe plan to upgrade them to support safe-string ?

2 Likes

I asked John Whitington, the author of camlpdf: camlpdf doesn’t accept images as input, only pdf.

Oh that is sad. Strange it doesn’t. You can use OCaml FFI and call one of these Rust libraries then:

@fccm: I’m interested in helping you doing that. You just need to know that I never wrote any Ocaml bindings.
As as a safe workaround for my present program, which way would you recommend: using Sys.command , Unix.execv or another function?
Thanks

@Luc_ML @fccm @dbuenzli I could easily fix the OCaml part of the bindings, but failed to compile the C part: the build relies on a Magick-config binary that is nowhere to be found… It’d be great to update this library so if there is a repo somewhere I can at least submit the patch for string-safe compatibility.

(Note : I do not know the camlpdf library)

This seems a limited answer : the PDF langage support PNG and JPG images in the document. The library should allow you to create a new page, and insert an image as a ressource (A minimal example is given, in the pdfreference see section 8.9).

You have to manage by yourself the page layout and the graphic size with the appropriate operators, but you can generate a PDF containing the image you want.

The requirement is to make a pdf file from a png file.
I could easily get a pdf with the following shell command:
$ convert foo.png foo.pdf

For the time being, camlpdf doesn’t take image file as an an input. You must feed it with a pdf.
How can we do that manually, as you are suggesting, without camlpdf? and without ImageMagick?

EDIT : I see how to handle the image that is in the dictionary but I don’t see yet how to specify the path to the png image file.
https://www.adobe.com/content/dam/acom/en/devnet/pdf/PDF32000_2008.pdf#G7.1851751

I do not suggest to do it without camlpdf, but I say that camlpdf shall provide all the required function to the raw pdf structure in order to generate the document as you want. This require for you to know the pdf structure, and the png structure.

The pdf document does not handle link to the file, you have to give the binary data directly in a stream, and give all the image information in a dictionary like in this pdf object :

<<
/Filter /FlateDecode
/Type /XObject
/Subtype /Image
/BitsPerComponent …
/Length --STREAM LENGTH--
/Height --IMAGE HEIGHT--
/Width --IMAGE WIDTH--
/DecodeParms <<
    /BitsPerComponent …
    /Predictor …
    /Columns …
    /Colors …
>>
/ColorSpace […]
>>
stream
[BINARY DATA HERE]

You can get more informations (and a pdf example) on this stack overflow message, but this not related anymore with OCaml… I know the pdf format a bit, but I’ve never used camlpdf.

It’s very low-level (as campldf).
To deliver, I’m going to use Sys.command convert foo.png foo.pdf and look at the exit code that should be 0.
Or is there another way to do that with stldib functions?

Just forked it (because besport put it on github first) and updated it for the new string type:
https://github.com/fccm/ocaml-imagemagick
There was not much to change:

  • many String.lowercase to change into String.lowercase_ascii
  • And only one error: a String.set to change

This is the first bindings I made in 2004 (and the first thing I released ever), and I’m not using it anymore since a while, so it would probably need some more love :slight_smile:
Any feedback is wellcome!

1 Like

In the Makefile you can probably provide what MagickCore-config did:

MAGICK_INSTALLED_BIN := $(shell which MagickCore-config)
MAGICK_PREFIX := $(shell $(MAGICK_INSTALLED_BIN) --prefix)
MAGICK_CLIBS := $(shell $(MAGICK_INSTALLED_BIN) --libs)
MAGICK_CFLAGS := $(shell $(MAGICK_INSTALLED_BIN) --cflags)

On my computer:

$ MagickCore-config --prefix
/usr
$ MagickCore-config --libs
-lMagickCore-6.Q16 
$ MagickCore-config --cflags
-fopenmp -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/usr/include/ImageMagick-6

Maybe your distribution uses pkg-config instead?
Edit:
There is: /usr/lib/pkgconfig/MagickCore.pc

$ pkg-config --cflags MagickCore
-fopenmp -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/usr/include/ImageMagick-6 
$ pkg-config --libs MagickCore
-lMagickCore-6.Q16

I don’t know how to request the prefix field.

$ grep prefix /usr/lib/pkgconfig/MagickCore.pc
prefix=/usr