I’m working on a project where I have to produce an image from a bigarray of pixels. Then, this image is used in a
src html field as data. See the following example:
<img src="data:image/<type>;base64,<data_content> />
type must be compatible with MIME type.
I tried to find a library that allows me to produce such data but I can’t find one to do what I want. The only one that suits is imagelib but there isn’t a release with the function I need. I use js_of_ocaml so I can’t use bindings…
Does someone have already encounter the problem and may have another solution ?
I suspect you are going to tell me I can’t use canvas ;–) but: take your bigarray draw it on a 2D canvas element and use the toDataURL function.
Now if you can’t use canvas because you are in a webworker but can choose the
<type> and you are willing to let that be
image/png then it’s quite easy to devise your own wasteful (doesn’t compress) encoder, see this old
caml-list discussion. You can find the code mentioned in this message on
Use that to produce bytes and then use the browser
btoa and you are done.
toDataURL on a canvas element. The canvas can be filled by using
putImageData. js_of_ocaml provides bindings for most of these APIs, including conversion of
Something like this should do the trick:
let base64_of_bigarray b width height =
let canvas = Dom_html.createCanvas Dom_html.document in
canvas##.width := width;
canvas##.height := height;
let context = canvas##getContext Dom_html._2d_ in
let image_data = context##createImageData width height in
let data = image_data##.data in
let buffer: Typed_array.arrayBuffer Js.t = Js_of_ocaml.Js.Unsafe.get data "buffer" in
let dst = new%js Typed_array.uint8Array_fromBuffer buffer in
let src = Typed_array.Bigstring.to_uint8Array b in
dst##set_fromTypedArray src 0;
context##putImageData image_data 0. 0.;
canvas##toDataURL_type (Js.string "image/png")
Thanks for your replies.
@copy I see that my question wasn’t complete. I apologize for this. I forgot to mention that I can’t use js_of_ocaml code only. My code will be compile to naive and js code so it must be functionalities usable both.
Why don’t you use the pure ocaml implementation of the PNG format that is available in imagelib? (this is not a binding). You say that there is not “the function you need”, what is this function that you need? If you have problems with PNG, have you tryed the BMP? What kind of images is it? logo, charts, pictures? If it’s logo or charts, you can probably use SVG instead.
The PNG ocaml module doesn’t allow me to export the array of pixels as a byte sequence.
The function I was talking about is
png_to_bytes. It’s always the same problem, I do not have a library to produce a data uri from an array of pixels.
The solution I have made, use virtual libraries and build two distinct things: one in the navigator and the other in the cli app.
Why don’t you add this missing function
png_to_bytes to the lib? imglib is open source, you can modify it to adapt it to your needs. Is there a technical difficulty? Maybe we can help you to resolve it?
This function already exists in the library but in the master branch (code) and not in the opam repository. The maintainer can’t do a release (issue). Furthermore, I have a compatibility problem with the
decompress version used by imagelib and the version needed by my project…
Using virtual libraries solved my problem. So, it’s not a problem anymore in my case. Nevertheless, thanks for your help proposition @ffcm
Documentation for the new version is now live at: https://rlepigre.github.io/ocaml-imagelib/imagelib/index.html
The release PR is pending approval in the opam-repository and should be available soon for fruition