A Linux Clipboard to JPEG Utility
Several months ago, I made the switch to Linux Mint (Cinnamon) as my primary OS for my computing activities. One utility that I used often on my prior OS was a utility that would capture images as they appeared on the clipboard, writing them to sequentially numbered files with a chosen name-prefix. I regularly try to save batches of images all in some sort of theme and I wanted a tool that could do this with Mint.
My first attempt ended up as a resource-intensive set of scripts that caused the laptop to heat up a bit when in a capture session. I knew that there had to be a simple answer so I used Google Gemini to get me into the ballpark with a new utility. Gemini suggested that I use functions in the GDK library to monitor changes in the clipboard. It then suggested that I use libjpeg to write the images. I asked it to write an example program that would wait until an image was placed on the keyboard and save it to a static filename, scaling it so that the width of the image was no greater than 600 pixels.
After a bit of back-and-forth, I had the basic utility that would save one image to a file called captured_image.jpg with a width no greater than 600 pixels. It would then loop and wait for another image to be placed on the clipboard.
I had to install some supplementary tools in order to do this:
sudo apt update
sudo apt install libgtk-3-dev gcc pkg-config
And then, to compile, I used the following command-line:
gcc `pkg-config --cflags gtk+-3.0` main.c -o clipboard_monitor `pkg-config --libs gtk+-3.0`
After a few back-and-forth prompting sessions, this is the source code that Gemini yielded:
https://github.com/jimlawless/c2j/blob/main/early_stuff/clipboard_monitor.c
I tested this for a while. I noticed that when I used ctrl-shift-prtsc to capture an image, the event notification fired twice causing the code to save the image twice. The problem is supposed to be a “feature”, so I needed to handle it in code in the final version of the utility. Other than that, it contained the exact mechanisms that I wanted. I needed to clean it up a bit, adding some command-line parameter support. I also had to add the sequential file-numbering support.
Here’s the version of the software that I’m currently using ( v0.80) :
https://github.com/jimlawless/c2j/blob/main/src/c2j.c
When you execute it on the command-line with no paramters, you’ll see:
Clipboard to JPEG v0.80 by Jim Lawless (and Gemini)
Syntax:
c2j [options]
...where options are...
-p filename_prefix # output filename prefix for image files (required)
-c number # starting number to use for counter in file suffix
-x max_width # maximum width of output image
-y max_height # maximum height of output image
-h # this output screen (help)
I’m afraid that I haven’t implemented the -y option yet, but the command-line parser doesn’t flag it as an error. To be honest, the only need I’ve had pertains to scaling the images based on the width, so I’m not sure that I’ll add the support for the -y option.
You can try the utility by running the follwing:
./c2j -p testimage -x 300
c2j will begin running in the console, writing each image to files with the prefix testimage … an underscore … and two-digit sequentially-numbered images that begin with 01. You can change the starting number with the -c option. The utility should continue to work for more than 99 files but the filenames won’t have a uniform length unless you change the sprintf format pattern that generates the output images.
Also note that I had to add a bit of a hack to prevent the dual-event generation for the same image. I used a statically-scoped local boolean variable called in_progress that returned from the function immediately if the prior invocation of the function hadn’t completed. Gemini suggested that I look at the timestamps of the clipboard image as a differentiator, but this seemed to work for my needs for now. However, machine characteristics differ and this could end up being a hack that doesn’t work for everyone.
I hope that you find the utility useful. It’s really about as complete as I need it to be, so there likely won’t be many updates. The experience did provide an overview of coding with the GDK which I found to be interesting.