Binding to the GD graphics library

Hallo,

I have started a binding to the GD graphics library here.
It currently supports only a tiny subset of the functions (mainly drawing primitives) included in this library
and will likely never be complete as it is purely a hobby project.

But as the GD library already exists for a long time, is easy to use and popular in
some fields), someone might still find it useful.

It is not the first Fortran language binding to the GD library, but the other approach I found
here seems to be nearly 19 years old and not using iso_c_binding for the language binding.

Cheers,
Johann

8 Likes

Small update:

Now I have added the pixel manipulation tools and very basic font support und basic support for copying areas of images.

Still missing (among others) is the support for Free Type fonts and more complex image manipulation tools (read and write).

Note that this library is not a real plotting tools but aims to be just a simple library binding for drawing things into pixel graphics (currently only *:JPG and *:PNG are supported) and read pixels from them.

The homepage of the binding now contains a list of already supported subroutines/functions.

3 Likes

The library now supports the use of OpenType fonts, so that
the most basic drawing functions are supported and the language
binding is almost usable for drawing.

Basically everything related reading files is still missing, but I am optimistic to
be able to integrate the most important pieces of that functionality
into the language binding soon.

Fortunately, libgd is well-documented.

Now, basic reading and processing of existing image data is supported.

1 Like

I’ve tested it successfully.
I suggest you post here and in your repository a picture to demonstrate what can be done with that library.

Now, basic reading and processing of existing image data is supported.

That’s an interesting point because there are other libraries we can use in Fortran for drawing, but not so many for reading/processing.

A final question: is it possible to access directly to the picture in Fortran? (an array?)

1 Like

Thanks for your feedback. I will add pictures when I have time.

I am no expert in GD lib, for my current experiments I have inquired the size of the image and read the color values pixel-wise.

I will provide more info later.

1 Like

I have seen there are some image filters:
https://libgd.github.io/manuals/2.3.3/files/gd_filter-c.html

1 Like

For most of these functions I have already written interfaces, but I have not comitted them and there exist no testcases.

What already exists is a test where an image (a flower) is separated in its r, g and b values.

1 Like

One caveat: I do not think that libGD was ever intended for scuentific image analysis, but rather to generate nice pictures. For example, only 8bit color encoding is supported.

1 Like

Here are some of the output image.

First three demonstrations of drawing primitives and the handling of OpenType Fonts:
tf_font


Then five images of a flower: The “normally” colored one is the original, then there is color separation in the red, green and blue channels (done manually via pixel-wise manipulation), and the result of a built-in function for edge detection.
flowers
flowers_red
flowers_green
flowers_blue
flowers_edge

The code for the edge detection is really quite simple (sorry for my somewhat sloppy programmings style without error detection):

program test_edge
  use iso_c_binding, only:  c_ptr, c_int
  use fortran_libgd
  implicit none

  type(c_ptr) :: im            ! image pointer
  type(c_ptr) :: output_image  ! file pointer  

  integer(c_int) :: status

  
  im= gdImageCreateFromFile("inpics/flowers.jpg"//c_null_char)

  status=gdImageEdgeDetectQuick(im)

  output_image =gd_fopen('outpics/flowers_edge.jpg'//c_null_char, 'wb'//c_null_char)
  call gdImageJpeg(im, output_image, -1)

  status = gd_fclose(output_image)
  
end program test_edge

gd_fopen and gf_fclose do not exist in libGD, but are just wrappers around fopen and fclose of the C standard library where I have added the prefix gd_ to avoid naming conflicts.

I will push the current version of the language bindings now, but not evertyhing is documented or tested yet.

4 Likes

The newest changes are now committed.
I will likely take care about the repository on weekend…

Do you (as author of the GTK C-binding) have any suggestions
on how I could make the binding more accessible
for people not very experienced in the C - Fortran interface?

I think the simplest way is to give them the basics of iso_c_binding: why they must append //c_null_char when they pass a string, why _c_int, what is c_double, c_ptr, etc. Expose that without assuming they should be familiar with C.

It could be a few paragraphs in the doc, or a short tutorial. You can also add some comments on that subject in the examples (tests) programs. And give them some links toward iso_c_binding stuff (see for example Fortran interoperability with C · vmagnin/gtk-fortran Wiki · GitHub).

1 Like

Concerning the iso_c_binding and iso_fortran_env intrinsic modules, it is also considered a better practice to state that the intrinsic modules must be used:
use, intrinsic :: iso_c_binding

Thank you for bringing this library to the community!

1 Like

Thanks a lot for your helpful hints on how to make the library more accessible
and the hint to mark intrinsic modules

I have tried to incorporate them into my code and documentation
and pushed the changes to github.

1 Like

Fine, your “images gallery” makes immediately the project more attractive in my opinion.

1 Like

I have extended the library a bit (wrapper for the popen function to open pipes, reading the the content of the image “object” in an array and vice versa) and played around with pipes and FFMPEG (using the tutorial by Ted Burke at
A simple way to read and write audio and video files in C using FFmpeg (part 2: video) | ad hocumentation • n. fast documentation of ideas and solutions. ).

I have now actually been able to do some video manipulation, although some workarounds had been necessary because of the lack of unsigned integer types in Fortran and the reading of ḿultidimensional arrays from pipes, which required mixed C-Fortran programing.

First results can been seen at Test video editing with GDLib and FFMPEG. (Warning: Some flickering) - YouTube .

There is still some cleanup and documentation work to do and I want to contact the author of the tutorial first, so the code for the example has not been published to GitHub yet.

3 Likes

Impressive!

Was the processing made in real time? Else how long did the preprocessing take?

1 Like

No, for a Ryzen 2 System with no parallelization at all of the side of my Fortran code or the C wrapper (gfortran11 -O3 -march=native) rendering the (Full-HD) video takes about 3-4 times the run time.

However, I still consider my code still rather badly optimized.

1 Like

Note that the approach shown in the blog post is not related to GDlib,
so in principle FFMPEG can be wich each graphics system that can associate
a pixel with a color value.

1 Like

I have now pushed some additional subroutines/functions along with a test program
and documentation to Github.

I have changed the demo video to be smaller (~ 1 MB, 320X240 pixels).
Therefore it looks rather ugly, but I did not want to litter my Git repository.

Furthermore the demo program is now simpler.

2 Likes