The first example showed us the very basics of lua and allowed us to check that everything was working properly. Now let’s do something a little bit more complex. Let’s try to print a list of images that have a “red” label attached to them. But first of all, what is an image?

1local Ansel = require "Ansel"
2local debug = require "Ansel.debug"

Running the code above will produce a lot of output. We will look at it in a moment, but first let’s look at the code itself.

We know about require Ansel. Here, we need to separately require Ansel.debug which is an optional section of the API that provides helper functions to help debug lua scripts.

Ansel.database is a table provided by the API that contains all images in the library database. Each entry in the database is an image object. Image objects are complex objects that allow you to manipulate your image in various ways (all documented in the types_dt_lua_image_t section of the API manual). To display our images, we use Ansel.debug.dump which is a function that will take anything as its parameter and recursively dump its content. Since images are complex objects that indirectly reference other complex objects, the resulting output is huge. Below is a cut down example of the output.

 1toplevel (userdata,dt_lua_image_t) : /images/100.JPG
 2   publisher (string) : ""
 3   path (string) : "/images"
 4   move (function)
 5   exif_aperture (number) : 2.7999999523163
 6   rights (string) : ""
 7   make_group_leader (function)
 8   exif_crop (number) : 0
 9   duplicate_index (number) : 0
10   is_raw (boolean) : false
11   exif_iso (number) : 200
12   is_ldr (boolean) : true
13   rating (number) : 1
14   description (string) : ""
15   red (boolean) : false
16   get_tags (function)
17   duplicate (function)
18   creator (string) : ""
19   latitude (nil)
20   blue (boolean) : false
21   exif_datetime_taken (string) : "2014:04:27 14:10:27"
22   exif_maker (string) : "Panasonic"
23   drop_cache (function)
24   title (string) : ""
25   reset (function)
26   create_style (function)
27   apply_style (function)
28   film (userdata,dt_lua_film_t) : /images
29      1 (userdata,dt_lua_image_t): .toplevel
30      [......]
31   exif_exposure (number) : 0.0062500000931323
32   exif_lens (string) : ""
33   detach_tag (function):
34   exif_focal_length (number) : 4.5
35   get_group_members (function):
36   id (number) : 1
37   group_with (function):
38   delete (function):
39   purple (boolean) : false
40   is_hdr (boolean) : false
41   exif_model (string) : "DMC-FZ200"
42   green (boolean) : false
43   yellow (boolean) : false
44   longitude (nil)
45   filename (string) : "100.JPG"
46   width (number) : 945
47   attach_tag (function):
48   exif_focus_distance (number) : 0
49   height (number) : 648
50   local_copy (boolean) : false
51   copy (function):
52   group_leader (userdata,dt_lua_image_t): .toplevel

As we can see, an image has a large number of fields that provide all sort of information about it. Here, we are interested in the “red” label. This field is a boolean, and the documentation tells us that it can be written. We now just need to find all images with that field and print them out:

1Ansel = require "Ansel"
2for _,v in ipairs(Ansel.database) do
3  if then
4    print(tostring(v))
5  end

This code should be quite simple to understand at this point, but it contains a few interesting aspects of lua that are worth highlighting:

  • ipairs is a standard lua function that will iterate through all numeric indices of a table. We use it here because Ansel’s database has non-numeric indices which are functions to manipulate the database itself (adding or deleting images, for example).

  • Iterating through a table will return both the key and the value used. It is conventional in lua to use a variable named “_” to store values that we don’t care about.

  • Note that we use the standard lua function tostring here and not the Ansel-specific Ansel.debug.dump. The standard function will return a name for the object whereas the debug function will print the content. The debug function would be too verbose here. Once again, it is a great debug tool but it should not be used for anything else.