In the following image you can see the list of options on the left and the corresponding array of image_buttons on the right.

Just like your code, each image_button has a unique name, so after you invoke your DCL, use
(action_tile "image_1" "(do_something 1)") ;; where do_something is your function that takes one argument being the integer for the image ID.
(action_tile "image_2" "(do_something 2)") etc.
Now notice the red border around the selected image_button. You can do that with this tiny gift...
(defun do_something (|n / |n |tile |x |y |x0 |y0 |color |hl)
(if (/= |slstyle |n)
(progn
(set_tile "slist" (setq |slstyle |n))
(foreach |n |nlist
(setq |tile (strcat "sl" |n)
|x (1- (dimx_tile |tile))
|y (1- (dimy_tile |tile))
|x0 0 |y0 0
)
(if (= |n |slstyle)
(setq |color -18 |hl 1)
(setq |color 0 |hl 0)
)
(start_image |tile)
(repeat 4
(vector_image |x0 |y0 |x |y0 |color)
(vector_image |x |y0 |x |y |color)
(vector_image |x |y |x0 |y |color)
(vector_image |x0 |y |x0 |y0 |color)
(setq |x0 (1+ |x0) |y0 (1+ |y0) |x (1- |x) |y (1- |y) |color |hl)
)
(end_image)
)
)
)
)
which relates the image_button picked to the list_box I call "slist" and the variable I call |slstyle
AND clears the red border around the previously highlighted image_button
AND draws a red border around the selected one.
All that because I wanted the user to have visual confirmation of his pick.
The only difference between yours and mine is that I named my buttons "sl1" sl2" etc.
BTW, the pipe symbol prefix "|" I used is from the days when local symbols weren't really local at all, so I made sure they each had unique names so I could set them to nil on program exit.