banner
Previous Page
PCLinuxOS Magazine
PCLinuxOS
Article List
Disclaimer
Next Page

Resizing Images, Revisited


by Paul Arnote (parnote)

As you might imagine, I work A LOT with graphic files in my position as the Chief Editor of The PCLinuxOS Magazine. So, I’m always looking for things that will “make my life easier” when working with graphic files. After all, why should I have to open up GIMP (or any other graphic file editor, for that matter) just to convert or resize an image when I can do it so much quicker from a custom bash script? Plus, the custom bash script allows me to perform the tasks on multiple images at once.

Eleven months ago, I updated a previous script that I use to convert between various graphic formats. In doing so, I added “protection” to prevent overwriting the original graphic file, as well as ensuring that the compression value of the image is between 0 and 100.

I often use my custom bash script to convert between different graphic formats. But, I probably use a different custom bash script to resize images even more. Like, almost daily. So, I figured why not give that custom bash script an update to prevent the overwriting of original graphic files, and to ensure that the compression value of the image stays within the range of 0 and 100.

As with all of my “other” custom bash scripts, this one can be run by anyone from the command line, or it can be used as a Thunar Custom Action. Since I pretty much use the Xfce desktop exclusively, that latter point is huge for me. It makes my life easier, and fits in with the way that I prefer to work perfectly.

The script takes graphic files/file names as its parameter. It can be one file, or a whole slew of files. Users of KDE or Mate desktops should also be able to use this script in a similar manner, but how to configure Dolphin or Caja as a service menu item is beyond the scope of this article.

A little later on in the article, I’ll illustrate a version of the script that does, with a few changes, work as a standalone program. This will allow those who fear (or avoid) the command line to create a launcher on a panel or on their desktop to create a wholly standalone program. This will also allow users of ANY Linux desktop to use this script, without having to delve into the in’s-and-out’s of configuring it for use in a file manager other than Thunar. While I’m definitely NOT a command line “commando,” I was able to figure out how to add the file selection dialog, and then use that information and method to select and to resize images, in bulk. There is NO reason to fear overwriting any of your original files, because I’ve eliminated that risk. The ONLY time you have to worry about overwriting ANY of your images is if you use the original image, and enter the same dimensions and compression ratio, and then it will overwrite the OLD version of the image with the same dimensions and compression ratio. However, your original file(s) are safe from being overwritten.


The “New” Script

I originally wrote about the “original” version (scroll down to the “Resizing” section of that article) of the image resizing script a little over 10 years ago (Egads! … It’s hard to believe it has been THAT long ago!). Over the years, I’ve tweaked it, and then tweaked it some more, and then tweaked it some more again. You get the idea. This new version of the script is called Img-resize4.sh. You can download it from the magazine’s website, or type it in if you prefer.

If you choose to download it from the magazine website, be sure to remove the “.txt” file extension from the downloaded file, store it where you typically store your bash scripts, and make the file executable. I store all of my bash scripts in my ~/bin directory, which is in my system’s path statement. That way, I don’t have to specify a path to my bash scripts.

So, below is the new script for resizing your images. In the image, I’ve included the line numbers from my text editor, to make it easier for you to follow along.

Img-resizer4.sh

Img-resizer4.sh-2
 
Resize1

Of course, the script starts off with the typical bash script shebang, while line 3 initializes a variable to a value of “1.” Lines 5 through 8 allow you to set the width of your resized image, in pixels. Smaller widths generate smaller file sizes, and conversely, larger widths generate larger file sizes. I would advise that you NOT go much above the size of the original image, or you’ll likely get pixelization of the image. There are other tools that do a much better job of making your images bigger … but that’s an article for another time.


Resize2    Resize3

Lines 10 through 15 allow you to choose the file format that you want to convert your image(s) to. Lines 17 through 24 allow you to specify the image quality setting. The higher the number, the higher the quality, and the larger the file size.

Resize4

Lines 26 through 32 allow you to choose what directory you want to store your resized images in. If you want to store them in the same directory as the original file, just enter ./ as the directory. Similarly, entering ../ as the destination directory will place the resized images in the parent directory of whatever directory your original images are currently stored in.

Lines 34 through 41 make some changes to the image background value, depending on whether you’re converting to PNG or JPG files. Line 43 adjusts the resolution (width) of your images to accommodate the one pixel black border that the script puts around the edge of the resized image.

Lines 45 through 54 is where the “magic” happens. The list of images sent to the script as command line arguments are cycled through in a “for” loop, and each one is assigned a new filename, with the resolution and quality level, and with the new file extension. The heavy lifting for the script is done by ImageMagick’s convert command. That variable we declared at the very beginning, in Line 3, is incremented to allow the progress bar to be updated properly.


Resize5

Line 56 is what’s responsible for displaying the progress bar and dialog box that appears while the script is processing the images you “fed” it. If you’re only doing a small number of images, you might never even notice the progress dialog box appears. However, you will appreciate the progress bar when processing a large number of files. Line 58 exits the script cleanly, after all of the images have been processed.

Like I mentioned earlier, the script is designed from the outset to work either from the command line, or from a Thunar Custom Action. To set up the Thunar Custom Action, your custom action windows will most likely look like one of these shown below.


ThunarCA-1 ThunarCA-2

Everything works with this version of the script exactly as I intended for it to. The script is small, and it is F-A-S-T.


The “Standalone” Script

In the process of updating my image resizing script, I decided to try making a standalone script that can be run from a launcher on a panel or from the desktop. Virtually ALL of the functionality of the previous version is maintained, but there are some slight differences, which I’ll reveal as we go through the script. After all, the previous version has all of the data it needs passed to it by way of the command line. This standalone version has to be “fed” the data it needs, entirely from GUI elements.

As with the previous script, you can download it from the magazine’s website. And, as with the previous script, delete the “.txt” file extension, save the script where you usually save your bash scripts, and make the file executable. This version of the script is named Img-resizer5b.

A lot of the script remains the same as with the previous version, with some notable differences. First, here’s the script that works as a standalone program.


Img-resizer5b-1Img-resizer5b-2

So, instead of rehashing everything I’ve already told you about the previous script, I’ll just talk about what is different.

;
Resizer5-FileSelect

In Lines 5 through 9, the Zenity file selection dialog is displayed. The Zenity command is restricted to displaying ONLY those files which match the file extensions listed: PNG, JPG, WEBP, AVIF, GIF, BMP and TIFF (and directories). I’ve also made it so that it will function with images that use all lowercase letters in the file extension, or with images that use all uppercase letters in the file extension. It also allows the selection of multiple files for resizing. The separator is set to a blank space between files. Without specifying the separator, it defaults to a “|” pipe symbol as a separator. By default, the read command uses a blank space as its delimiter, so setting the separator to a blank space accommodates the use of the read command to create the array. In Line 9, the selected files are put into an array for later processing.


Resizer5-output-dir

From Lines 33 through 41, we have to alter a few things. First, we have to alter the appearance of the “Destination Directory” dialog box. Second, we also have to construct a proper path for the new image, and create the destination directory, if it doesn’t already exist. With this standalone version of the script, you cannot specify the parent directory (../) as the destination directory. However, if you want to save your resized images in the same directory as your original image files (remember, your original files are safe from being overwritten), just leave the text entry field empty or blank.

When we selected files in the Zenity file selection dialog box, the returned file names were in the form of a full path to the specified file(s). So, to both properly create the new directory, and to specify a proper path for the destination file, we have to deconstruct and then reconstruct a proper path for that destination file. The CURR_PATH variable grabs the path from the first file selected in the array (${FILES[0]}) using the “dirname” command. Remember we put all of the information for the selected files in an array. So all we’re doing here is copying the path information for that first file in the array into the variable CURR_PATH. Then, we construct a proper path for the destination file by adding $CURR_PATH and $DIR (the directory name we specified in the Destination Directory dialog box) to one another, properly formatted, and save it in the variable $NEW_DIR. We’ll use the $NEW_DIR variable later on, when the ImageMagick “convert” command is outputting the new file.

Jump forward to Line 54, and we have to change the for loop so that it pulls the filenames from the array we set up in Line 9. As part of our “construction” efforts to reconstruct a proper file name, the path information is stripped (basename) from each file in the FILES array as they are processed. Then, we combine the $NEW_PATH information, with the filename currently being processed, along with the other file name descriptors to prevent overwriting the original files, to create a fully valid and proper path to the new file output by the ImageMagick “convert” command.

Nearly all of the remaining lines of the script are exactly as they are in the previous version. The script does work well for resizing images. I’ve tried and tried and tried to “trip it up,” and have been unsuccessful in those attempts. In every case or situation I threw at it, it performed flawlessly.

You don’t even have to specify a destination directory, if you don’t want to. I just thought this might be a nice “feature” that some users might like to have. Your resized image files will be placed in the same directory that contains your original graphic files. Since your original files are safe from being overwritten, this isn’t that big of a problem. Later, if you change your mind, you’ll just have to go into that directory that contains your original and resized graphics, and move the resized image files to another directory manually, if that’s what you desire. But the ability to create a new destination directory for your resized images eliminates having to manually move your resized graphic files at a later date, saving some time later on. Plus, it also helps keep things nice and tidy.


Caveats

In all honesty, I can only list ONE caveat for using either one of these scripts, to the best of my knowledge. That one caveat is that your graphic file names should NOT have a space in them. Remove or replace spaces in the file names you submit to these scripts to process, or they could cause the script to not complete.

Of course, “this ain’t Windows, ya’ know,” so you shouldn’t be using spaces in your file names anyway. If you do, you may get away with it for a while, but eventually, it WILL come back to bite you on your hind side. That is because in so many cases, a space acts as a delimiter to so many tools Linux users commonly use. So, it’s best practice to avoid using spaces in your file names, if at all possible.

It’s especially unlikely that graphic file names with spaces in them will not properly populate the array used in the standalone version of the script. The “read” command that sets up the array uses the space as a delimiter, so the array may not have the true path or file name as some of its array members. Most likely, the array will not point to a fully qualified path and file name.

It might not be a bad idea to add a line near the beginning of the script (after Line 4, but before any other dialogs are displayed) to the script to warn users about NOT using files with spaces in the file name. It might look something like this:

zenity --warning --title=”WARNING!” --timeout=15 --text=”DO NOT run the script\non files containing spaces\nin the file name!”

This will cause the warning dialog box to appear with the defined text, and then automatically disappear after 15 seconds. Of course, you could always hit the “OK” button before the 15 seconds is up, dismissing the dialog box warning message earlier than 15 seconds.

If you feel so inclined, you could put in a function or command to remove or replace spaces from the file names. I’ll leave that as an exercise for you to undertake, if you want. Since I avoid spaces in file names like the proverbial plague, it’s a non-issue for me, and I won’t be undertaking any such task. I also want to keep the script lean, and making the script “behave” with file names containing spaces isn’t exactly going to make the script be as lean as it needs to be, or that I want it to be. “More” is not always better.


Summary

I hope you find these scripts as useful as I do. In my position as the magazine’s Chief Editor, there’s hardly a day that goes by that I don’t use one of these image resizing scripts. I mean, I really use them a LOT.

Rest assured that they do their intended job perfectly. I don’t have time to waste on scripts that don’t work properly or perfectly, and I suspect it’s the same for the rest of you, as well.



Previous Page              Top              Next Page