banner
Previous Page
PCLinuxOS Magazine
PCLinuxOS
Article List
Disclaimer
Next Page

Xfce Power User Tips, Tricks & Tweaks: Working With Graphics

by Paul Arnote (parnote)

We've all run into situations where we needed to change from the PNG graphics format to the JPG graphics format ... or vice versa. You have to be careful, however, so that you don't overwrite your original files. Overwriting your original files is always B-A-D.

There is no doubt that the ImageMagick set of graphic commands are the most powerful ones ever conceived. There are literally NO limits to what you can do with them. One such ImageMagick command, mogrify, can be a very dangerous one. Without "putting a leash on it," mogrify will overwrite your original files with a smile -- and without any warning. In a way, mogrify is the "dd" command of the ImageMagick graphics commands. The other most commonly used ImageMagick command is convert. There are others, but these are the ones that most people use most often.

So, the secret to utilizing the ImageMagick mogrify command is to do one of three things. First, you can (read that you should) always make backup copies of your images, and only perform your work on the copies. The second thing you can do is "put a leash" on the mogrify command, and it's easier to do than you might think. In keeping with a "theme" here (this is, after all, an article about Xfce Power User Tips, Tricks & Tweaks), the latter is exactly what we are going to do, via a Thunar Custom Action. The third thing you can do is avoid the use of the mogrify command altogether. However, you will also be limiting yourself from using one very powerful ImageMagick command.

Don't worry. If you are not an Xfce user, there is still an ample amount of information you will find useful for working with graphic files. In fact, every one of the scripts listed below can also be utilized as ... well ... standalone scripts, that you can use from the command line in a terminal session.


A Brief Review Of Graphics Formats

Before we get started, let's do a slight review of three leading graphics formats and how your choice of which one to use will affect the results you get. There are two basic types of image formats: bitmapped, or pixel based graphics formats, and vector based graphics formats.


Original JPG image from camera.

JPG files are a pixel-based graphics format, and use something called "lossy compression." This means that the JPG format will basically scan your image and discard data that it feels is irrelevant or unnecessary. As a result, every time you edit - save - re-edit - re-save - re-re-edit - re-re-save ... etc. a JPG file, a small amount of the data is discarded each time. Some graphics aficionados can actually start to see noticeable image degradation by the third generation JPG image. Most everyone else can start to see it by the fourth or fifth generation without too much difficulty. Of course, all of this is done to produce smaller file sizes. Basically, the JPG format produces smaller files sizes at the expense of quality.



Top left: snippet from original JPG file, as shot by the camera. Top Right: second generation PNG file snippet. Bottom Left: second generation JPG file snippet. Notice the image already breaking up in the eye on the left and around the glasses on the top of the head. Bottom Right: sixth generation JPG file snippet. Breakup around glasses getting more pronounced, more pixelation around the left eye, and the colors are becoming more muted.

PNG files, also a pixel-based graphics format, use something called "lossless compression." The advantage here is that none of the image information is discarded with each edit and re-saving of the PNG file. The trade off is that the PNG files are slightly larger than their JPG counterparts, but preserve quality at the expense of file size. PNG files also allow you to have transparent backgrounds, something that JPG files can't do. The PNG format came about as an open standard to provide an alternative to the use of JPG and GIF files, which (at that time) were licensed and closed standards. And yes, along the way, many computer users were threatened with lawsuits for using these formats without a license. Along the way, the developers of the PNG format sought to overcome some of the shortcomings of the JPG file format, like the lack of ability to use transparent "colors" and JPG's "lossy compression" pitfalls. Since then, the JPG and GIF formats have been released from their "closed" and proprietary status, and anyone can use them now without fear of being sued for using them without a proper license.

SVG files are the odd duck in this collection of graphics formats. They are a vector-based graphics format. Basically, all of the image information in vector-based graphic files is stored as mathematical equations, which can be scaled as large or as small as you want, with absolutely no loss of quality and no pixelation. They also produce very small file sizes. The trade off is that there are many programs that cannot properly display SVG files. SVG files also don't lend themselves well to photographic images. They are better suited for "drawn" images that are created in a vector-based drawing program, such as Inkscape, Xara Extreme and LibreOffice Draw.

Sure, there are other graphics formats, such as GIF, TIFF, RAW and BMP files (the latter two produce monstrous file sizes, since they employ virtually no compression). In fact, there are many more graphics formats out there, but most people will be working with one of the first three file formats (JPG, PNG or SVG) I mentioned more than 95% of the time.


So what does this mean for you?

Let's say you have a collection of over 1,000 images from your most recent vacation. It was the "vacation of a lifetime." You shot them with your new digital camera (most of which save your images as high quality JPG files). Let's complicate the situation a little, too. You misplaced/lost your extra memory cards, or you simply didn't bring enough of them to hold all of the images you shot. So, you transfer those images to the laptop you took along with you so you can delete the originals from the memory cards, freeing up space so you can continue shooting those gorgeous pictures. You want to perform some edits -- cropping, resizing, color enhancements, etc. -- on those images before posting them to your online photo sharing site.

If you crop the image and re-save it, then re-size it and re-save it, then enhance colors and re-save it, you're already looking at a fourth generation JPG file. As a result, you will be also looking at an image that is already exhibiting significant image quality degradation. Fortunately, there IS a better way, one that preserves the image quality while enabling you to preserve as much of the image quality as possible. That method is to convert your images to PNG files, perform your edits on the PNG files, and then convert them back to JPG files before you upload them to your favorite photo sharing site. (We'll talk more about SVG files a little later on.)

So now, we need to put that leash on the ImageMagick mogrify command, and use it to convert our image files between formats. REMEMBER: ONLY EVER WORK ON COPIES OF YOUR IMAGES! Do NOT risk overwriting your original images, under ANY circumstances! One slip or one misplaced command and all of your images from your vacation of a lifetime could be G-O-N-E ... forever! They will be irretrievably replaced with the altered versions. And NEVER, EVER directly edit the images stored on your camera's memory card. If you do, you are just asking for trouble. It's not a matter of "if" you will slip up, but "when." Consider yourself properly warned.

With the warning in mind, do not fear what we are about to do. Remember that you will be working on COPIES of your images, and the ORIGINALS are safely tucked into their own, separate directory (for some reason, I cannot stress this enough).



Lucky for you, you are an Xfce user and can create a Thunar Custom Action to perform the file format conversions in a relative blink. In Thunar, go to Edit > Configure Custom Action. On the first line, give it a name. I called it "Convert JPG To PNG." On the second line, give it a description. I entered "Convert all the JPG images in the directory to PNG files." On the third line, enter the following command:

mogrify format png *.jpg

Under the "Appearance Conditions" tab of the Configure Custom Action dialog box, enter *.jpg in the File Pattern box, and only check the checkbox next to "Image Files."

In its most basic form (as shown above), this mogrify command changes all the JPG images in a folder (*.jpg) to PNG images (format png) -- all without overwriting your original images (which is a distinct possibility if you are not careful with the mogrify command). The bad thing about this command, used in its most basic form, is that all of your new PNG files are now mixed in with all of your JPG files -- in the same directory.

Not only does this get messy, but it also greatly increases the chances for you to accidentally perform your edits on the original file, instead of the PNG copy of the file. It would be better if our converted images were in their own directory, keeping them separated from the originals. Let's change the command (third line) of the custom action to this:

mkdir Copies && mogrify -path ./Copies format png *.jpg

Now, this is better. First, we make a directory called "Copies" (mkdir Copies), and tell mogrify to place the converted images in the Copies folder (-path ./Copies). However, there is one problem with this command. If the "Copies" folder already exists, the command will exit with an error when executing the mkdir command (since you're trying to create a folder that already exists), and it never gets around to executing the second part (the mogrify part) of the command.

When this happens, there is no warning or notification from Thunar that there was a problem of any kind. So, some of the "reliability factor" is removed from this Thunar Custom Action. After all, when you select and use the custom action, you don't want to have doubts in the back of your mind about if the command worked or not. You simply just want it to work. Period. So, let's see if we can improve this further.

D="$(zenity --title="Directory Name" --entry --text="Please enter the directory name")"; mkdir $D && mogrify -path $D -format png *.jpg

While the command is getting longer and a bit "messier," this is definitely an improvement. We use Zenity to ask the user for input, namely the name of the directory we want to place our copied images into. This command is better in that it allows the user (you) to specify a directory name. However, if you enter the name of a directory that already exists, the command will fail as miserably as the previous incarnation of the command -- and again, without warning or notification that it failed. It's great that we have a choice of the directory name now (via the user input), but the command could still fail. Relying on user input is fraught with potential for failure, and that source of failure is the user themselves. Sometimes, you have to protect users from themselves. If only we could make the creation of the directory conditional on whether or not it already existed.

Ah! But we can! Let's try this version of the command:

D="$(zenity --title="Directory Name" --entry --text="Please enter the directory name")"; if [ ! -d $D ]; then mkdir $D; fi && mogrify -path $D -format png %F

Now, this version is the messiest of all, but achieves perfectly what we are trying to do, and performs -- in all cases -- as it should. In this version, we use a Zenity dialog box to ask the user to specify a directory where we want to make our copies. We then use a conditional if-then statement to check to see if that directory already exists, and if it doesn't, to make that directory. Then, we continue with the mogrify command as we employed it previously, telling it to convert all the JPG images in a directory to PNG files, and place them in the directory specified by the -path $D statement, which also happens to be the same directory we specified in the Zenity dialog box.

Under the "Appearance Conditions" tab, place a checkmark in the check box next to "Image Files" only, and set the file pattern to *.jpg;*.JPG.



Also, you will have to have separate custom actions, one for every graphics file type you are wanting to potentially convert from or to. So, just restricting to PNG, JPG and TIFF files, you now have six slightly different custom actions, each one tailored for a specific type of graphics file conversion.

So, is there a better way to "automate" the process, and create a directory with a unique name every time it is used? Why, yes there is! We can make a directory whose name contains the date and time of creation. Extending the date command out to include seconds as part of the time that's in the name of the directory, we can create a directory with a unique name every single second.

But, to do this, we will have to create a bash script to handle the automatic directory naming. First, Thunar cannot/will not recognize or interpret the date command when used in a custom action command. Also, because we're using the same directory name twice (once in the mkdir command, and once in the mogrify -path switch), we'll also need to handle the file conversion in the bash file. This will insure that the same directory name is used throughout the entire command.

There are added bonuses to using a bash script. First, I can drop the use of the "more dangerous" ImageMagick mogrify command, and switch over to using the safer ImageMagick convert command. Second, I can now perform the file conversions on only the images I select, instead of doing all of the images in a directory. Third, I can make the bash script handle either PNG or JPG or TIFF files (or any other kind of graphic file), and the Thunar Custom Action will call one bash script to provide whatever type of graphic format conversion I want to handle. (Note: we'll create a special bash script later on to handle only SVG files, since their conversion process requires different parameters). Fourth, I can also "dress up" the entire process by displaying a progress bar to give the user feedback that it is working. Fifth, I can provide user interaction by asking for user input for less critical parts of the process, using Zenity dialog boxes.



In my opinion, the critical part of this process is the creation of a directory with a unique name. That is the point in the previous custom action commands where things break down and fail. Even if the user messes up on the user input of the less critical aspects of the process, there is no harm done, since all of the original files remain intact and unchanged.


The Convert Image Script

So, here is the bash script, which I've called convert-image.sh, that we'll use to convert between different pixel-based graphic file formats:


#! /bin/sh                                                      

# Increment and count the number of files passed to the script
# for later use in the progress dialog box
n=1

# Ask for the destination graphic image format to change to
# Next line is entered all on one line
EXT=`zenity --title="Convert Image" --entry --text="Please 
enter the image format to convert to (e.g. PNG, JPG, TIFF, etc.)"`

  if [ $? == 1 ]; then

     exit
  fi

# Make sure the file extension is in lowercase text
declare -l EXT
EXT=$EXT

# Ask for the quality level of the copied images
# Next line is entered all on one line
QUAL=`zenity --title="Please enter quality" --entry --text="100 
= Full Quality, 75 = 75% Quality, 50 = 50% Quality"`

  if [ $? == 1 ]; then

     exit
  fi

# If the destination image format is PNG, set background to none
# (transparent) and set the quality levels, which differ from JPG
if [ $EXT == "png" ];
  then
     BACKGROUND="-background none"
     QUALITY=$(($QUAL / 10))
  else
     BACKGROUND="-background white"
     QUALITY="$QUAL"
fi

# Generate the new directory name, and set it to uppercase text
NEW_DIR="./"$EXT"-"$(date +"%m%d%y-%H%M%S")
declare -u NEW_DIR
NEW_DIR=$NEW_DIR
mkdir $NEW_DIR

# Pause for one second, just to be sure that everything that
# needs to be done has been done
sleep 1

# Cycle through the selected files, performing the conversion
# one file at a time
for file in $@; do
    if [ ! -e $file ]; then
       continue
    fi

     # Get just the filename, without the original file extension
    name=$( echo $file | cut -f1 -d.)

     # Convert the file and write it out to the destination file
     # Next line is entered all on one line
    convert -quality $QUALITY $BACKGROUND $file $NEW_DIR/${name}.$EXT

     # Set up the information to display in the progress dialog box
    echo $(($n * 100 / $#))
    echo "# Processing file: $file"
    let "n = n+1"

# Next line is entered all on one line
done | (zenity  --progress --title "Converting to "$EXT"..." --percentage=0 --auto-close --auto-kill)

exit 0

Enter the above text into your favorite text editor (Mousepad is the default for Xfce). I have created a directory in my /home directory called "Scripts," and that is where I keep all of my scripts. Save the file. As I mentioned earlier, I named the script "convert-image.sh." Don't forget to make the script executable after you save it. You can safely remove the comment lines (the lines that start with #) from the script, if you choose.

Now, create a new Thunar Custom Action (Edit > Configure Custom Actions...). On the first line, enter a name. I called mine, simply, "Convert Images." On the second line, enter a description. I entered "Convert the selected files to the user defined graphic format." On the third line, enter the following command:

$HOME/Scripts/convert-image.sh %N

Of course, if you have your script stored somewhere other than a Scripts directory in your /home directory, you will need to be sure to point it to the proper location. You have to admit that this is a much cleaner command than what I demonstrated earlier.

Choose an icon for your new custom action. Under the "Appearance Conditions" tab, the file pattern should be *, and the checkbox in front of "Image Files" should be checked.







Now, when you select multiple image files, or even just a single file, you can select "Convert Images" from Thunar's right click context menu. Supply the extension that represents the graphics format that you want to convert to, followed by the compression level to use (from 1 to 100). Your new directory will be created, the selected image files will be converted to the desired graphics format, and they will be placed into your new directory. All the while, your original images remain in their own directory, untouched and unaltered.


Converting SVG Files

Believe it or not, there are websites out there in the Internet wilderness that are charging people money to convert SVG files to "regular" pixel-based graphics formats. My initial response was, "you gotta be kidding, right?" I wish I was kidding, but it's true. Charging people money to do something so simple almost seems criminal to me.

Thankfully, converting SVG files to those "regular" graphics formats isn't much different than how we converted between the other, pixel-based graphics formats. But it is different enough that it was easier to just create a separate bash script to handle the conversions from SVG files, rather than getting entangled in a bunch of conditional if-then-else statements.

Here is that bash script, which I've called convert-svg.sh:


#! /bin/sh                                                      

n=1

# Next line is entered all on one line
EXT=`zenity --title="SVG Convert" --entry --text="Please 
enter the image format to convert to (e.g. PNG, JPG, etc.)"`

  if [ $? == 1 ]; then

     exit
  fi
declare -l EXT
EXT=$EXT

if [ $EXT == "png" ];
  then
     BACKGROUND="-background none"
  else
     BACKGROUND="-background white"
fi

# Next line is entered all on one line
DEN=`zenity --title="Please enter density" --entry 
--text="72 = 1:1, 144 = 2x size, 36 = 1/2 size"`

  if [ $? == 1 ]; then

     exit
  fi

NEW_DIR="./"$EXT"-"$(date +"%m%d%y-%H%M%S")
declare -u NEW_DIR
NEW_DIR=$NEW_DIR
mkdir $NEW_DIR
sleep 1

for file in $@; do
   if [ ! -e $file ]; then
       continue
   fi

   name=$( echo $file | cut -f1 -d.)

# Next line is entered all on one line
   convert -density $DEN $BACKGROUND $file $NEW_DIR/${name}.$EXT

   echo $(($n * 100 / $#))
   echo "# Processing file: $file"
   let "n = n+1"

# Next line is entered all on one line
done | (zenity  --progress --title "Converting to "$EXT"..." 
--percentage=0 --auto-close --auto-kill)

exit 0

It works much like the previous script does, except it asks for some different information, on account of what's needed to do a proper conversion from the vector-based SVG graphics format to a pixel-based graphics format. In fact, most of the differences are in how the ImageMagick convert command is called, and the input of the "density" value for the SVG file.

The "density" value is an interesting one. The default value is 72, which produces a 1:1 image. That's just another way of saying it produces an image that is the same size as the SVG image size. If you want the image to be ½ size, enter a value of 36. Similarly, if you want to produce an image that is twice the normal size, enter 144 as the density value. So, by working out the math, a density value of 12 will produce an image that is one-sixth the size of the SVG image, and a density value of 108 will produce an image that is 1.5 times larger than the SVG image.

The density value allows you to scale an image up or down, without pixelation and without producing any "jaggedy" edges in the converted image. That is one of the nice things about SVG files. Because the file content is mathematically based, it can be scaled as large or small as you want, with excellent clarity and no loss of quality. The same cannot be said for pixel-based graphic formats, which will pixelate and exhibit a significant loss of quality whenever you attempt to scale the images past their capabilities to produce and display a clear picture. That limit varies, depending on the initial resolution (dpi) of the image, the degree of compression utilized to produce that particular image, and the size of that image, among other factors.

Enter the script above in your favorite text editor. Save the file. I called mine "convert-svg.sh," and placed it in my $HOME/Scripts directory, where I store all of my custom scripts. Be sure to mark the script as executable.







So, to utilize our script as a Thunar Custom Action, start off just like we did with the previous script by creating a new custom action. On the first line, enter a name. I called mine "Convert SVG." On the second line, enter a description. I entered "Convert selected SVG files to user specified bitmapped graphic format." On the third line, enter the following command:

$HOME/Scripts/convert-svg.sh %N

Choose an icon for your new custom action. Under the "Appearance Conditions" tab, set the file pattern to *.svg;*.SVG, and place a check in the checkbox only in front of "Image Files."

Now, whenever you right click on one or a group of SVG files, you will be able to select "Convert SVG" from the right-click Thunar context menu. Enter the file extension you want to convert the file to, followed by the density value. Your selected SVG files will be converted to the file format you indicated with the file extension, sized according to the density value you entered, and placed in their own sub-directory.


Image Resizing

Resizing a group of images is another task that can easily be accomplished from a Thunar Custom Action. While the ImageMagick convert command can be called for individual files and used to resize images by just using the convert command, we need a bash script if we want to perform the action properly on multiple files.

Here is the script I use to resize a group of images, and I call it Img-resize.sh:


#! /bin/sh                                                      

n=1

# Next line is entered all on one line
RES=`zenity --title="Image Width" --entry --text="Image 
Resizer -- Please enter the image width (e.g. 600)"`

  if [ $? == 1 ]; then
     exit
  fi

# Next line is entered all on one line
EXT=`zenity --title="File Extension" --entry --text="Enter 
the file extension you want to convert to (e.g. JPG, PNG, TIFF)"`

  if [ $? == 1 ]; then
     exit
  fi
declare -l EXT
EXT=$EXT

# Next line is entered all on one line
QUAL=`zenity --title="Image Quality" --entry --text="Enter the 
image quality (1 - 100)"`

  if [ $? == 1 ]; then
     exit
  fi

if [ $EXT == "png" ];
  then
     BACKGROUND="-background none"
     QUALITY=$(($QUAL / 10))
  else
     BACKGROUND="-background white"
     QUALITY="$QUAL"
fi

REZ=$((RES-2))

NEW_DIR=./Resized$RES
if [ ! -d $NEW_DIR ]; then
  mkdir $NEW_DIR
fi
sleep 1

for file in $@; do
   if [ ! -e $file ]; then
       continue
   fi

   name=$( echo $file | cut -f1 -d.)

# Next line is entered all on one line
   convert -resize $REZ -quality $QUALITY $BACKGROUND -bordercolor 
black -border 1x1 $file $NEW_DIR/${name}_$RES.$EXT

   echo $(($n * 100 / $#))
   echo "# Processing file: $file"
   let "n = n+1"

# Next line is entered all on one line
done | (zenity  --progress --title "Resizing..." --percentage=0 
--auto-close --auto-kill)

exit 0

Using Zenity dialog boxes, you enter the width (in pixels) that you want the new images to be, the file extension of the graphic format (jpg, png, tiff, etc.) you want them converted to, and the quality setting to use (1 - 100) for the destination file.

After you've entered your settings in the Zenity dialog boxes, a new directory is created if it doesn't already exist. The new directory is named "Resizedxxx," with the "xxx" representing the new width of the images. So, if you specified resizing the images to 600 pixels, the new directory will be called "Resized600." If the directory already exists, then the current one is used, and the script skips trying to create the new directory.

The width that you entered is decreased by two pixels (the REZ=$((RES-2)) line) to accommodate the one pixel black border that's placed around the destination image. The new horizontal width of the image is appended to the end of the file name, and the destination image is given the file extension you specified in the Zenity dialog box. While the images are being resized, a Zenity progress dialog box is displayed to show the overall progress, and to display the name of the file that is currently being processed.

Note that if you rotate the images before resizing them, that will cause the height of the original image to become the width of the new, rotated image. If that width of that new image is less than the width you specified, the width of the destination image will be adjusted accordingly, and you will end up enlarging the image when you may have really meant to reduce the image size. So, it's best to perform any image resizing you may wish to do, before you rotate images.

So, now that you have a better idea of how the script works, let's make a new Thunar Custom Action from it. First, enter the script into your favorite text editor, and save the file. As I mentioned earlier, I called it "Img-resize.sh," and saved it in my $HOME/Scripts directory. Don't forget to make the script executable.

Next, create a new Thunar Custom Action. On the first line, enter a name. I called mine "Resize Images." On the second line, enter a description. I entered "Resize the selected graphic files." On the third line, enter the following command:

$HOME/Scripts/Img-resize.sh %N

Choose an icon for your new custom action. Under the "Appearance Conditions" tab, leave the file pattern set to *, and make sure that only the checkbox in front of "Image Files" is checked.









Now, when you select "Resize Images" from Thunar's right-click context menu, you will be able to resize either a single file, or a group of files, to one common width. If the image already exists in the destination directory, it will not be overwritten. If you wish to "redo" the same images at a previously used width, then you will need to first delete or move the existing files.


Image Rotation

Invariably, there will be some images that you will want to rotate. After all, it does get old having to cock your head to the left or right, just to be able to view your images with some semblance of normalcy.

Once again, as it was with the image resizing and the image converting we did earlier, you can easily set up an ImageMagick convert command to rotate single images, one at a time. The command, from a Thunar Custom Action, would be like this:

convert -rotate 90 %f %f to rotate images 90 degrees clockwise, or

convert -rotate 270 %f %f to rotate images 90 degrees counterclockwise.

But, if you've just sat down for a marathon photo editing session of your vacation photos, the last thing you want to do is something as mundane and simple as rotating images, one image at a time. Especially if you can do them all in one quick task. Your time would be better spent on headier editing tasks.

Once again, a custom bash script comes to our service, and allows us to process multiple files all at once. Here is the bash script, which I have named "Img-rotate.sh."


#! /bin/sh

n=1

# Next line is entered all on one line
RES=`zenity --title="Image Rotation" --entry --text="Enter 
the degrees rotation (e.g. 90, 180, 270)"`

  if [ $? == 1 ]; then
     exit
  fi

NEW_DIR=./Rotate$RES
if [ ! -d $NEW_DIR ]; then
  mkdir $NEW_DIR
fi
sleep 1

for file in $@; do
    if [ ! -e $file ]; then
       continue
    fi

    EXT=$(echo "${file##*.}")
    name=$( echo $file | cut -f1 -d.)

     # Next line is entered all on one line
    convert -rotate $RES $file $NEW_DIR/${name}-Rotate$RES.$EXT

    echo $(($n * 100 / $#))
    echo "# Processing file: $file"
    let "n = n+1"

# Next line is entered all on one line
done | (zenity  --progress --title "Rotating..." 
--percentage=0 --auto-close --auto-kill)

exit 0

The first thing you might notice is that this script is a bit shorter than the previous two that we covered. One reason is because we don't have a lot of user input, other than the degrees of rotation. The other reason is we're not converting formats. We're only changing the rotational orientation of the image, which is relatively simple. Most of the script consists of two things: dissecting the filename to parse out the filename and the file extension separately, then putting it back together again to form the destination filename, and processing through the images passed to the script, one at a time with the for-do-done loop.

The script checks to see if a directory named "RotateXX" exists (the XX representing the degrees of rotation specified by the user), and if it doesn't already exist, creates a new directory using the aforementioned naming convention. If the directory already exists, the existing directory is used.

Within the for loop, the file extension for each file passed to the script is extracted and saved to the $EXT variable, while the filename (without the file extension) is saved to the $name variable.

At the end of the convert command, a new filename for the destination image is assembled, starting with the sub-directory to place the image in, followed by the name with "-RotateXX" appended to the end of it (where the XX represents the degrees entered by the user), and the original file extension replaced at the end. Then, as with the other scripts, a Zenity progress dialog is displayed to give feedback about the overall progress and to list the file that is being currently processed.

So, that is how the script works. Enter the script into your favorite text editor, and save it. Now, let's set up and create our new Thunar Custom Action. On the first line, enter a name. I called it "Rotate Images." On the second line, enter a description. I entered "Rotate selected images the user specified degrees." On the third line, enter the following command:

$HOME/Script/Img-rotate.sh %N

Select an icon for you new custom action. Under the "Appearance Conditions" tab, keep the file pattern as *, and make sure that only the checkbox in front of "Image Files" is checked.





When you select image files to rotate, you can select "Rotate Images" from the Thunar right-click context menu. The selected files will be rotated, renamed and saved to the new directory, leaving your original images untouched and unaltered.

Here's a tip: to rotate images clockwise (to the right), select to rotate images 90 degrees, and to rotate images counterclockwise (to the left), select to rotate images 270 degrees.


Miscellaneous "Short" Graphic Commands

Not all graphic processing commands require a bash script. Many graphics tasks can be completed with one-liner ImageMagick commands. Here is a brief summary of some of those "one-liners" that you can easily use as Thunar Custom Actions (in addition to the ones we previously covered throughout the course of this article).

Add a one pixel black border:

Single images:
  Command: convert -border 1x1 -bordercolor black %f %f
  File Pattern: *
  Appearance Conditions: Image Files

Multiple selected images:
  Command: mogrify -border 1x1 -bordercolor black %F
  File Pattern: *
  Appearance Conditions: Image Files

Options:

  If you want a 2 pixel border, change the 1x1 to 2x2. Similarly, 
  if you want a 5 pixel border, change the 1x1 to 5x5. If you want 
  a different color border, change "black" to "blue" or "red" or
  "green" or whatever other color you want to use.

  

Convert FORMAT1 To FORMAT2:


Single Images:
    Command: convert %f `basename %f .jpg`.png
    File Pattern: *.jpg
    Appearance Conditions: Image Files

Variations:

    Swap the .jpg and .png around in the command to convert a PNG 
    file to a JPG file. This also works for any other pixel-based
    graphic formats. Replace .jpg in the original command with the 
    file extension of the original file, and replace the .png in the 
    original command with the file extension of the file format you 
    are wanting to convert to. Be sure to change the file pattern
    accordingly in all of these variations.

    With the `basename %f .jpg` part of the command, the 
    old file extension is stripped from the original file name,
    and the new     file extension (.png) is appended to the destination filename.

Multiple Images:
    Command: mogrify -path PNG -format png %F
    File Pattern: *
    Appearance Conditions: Image Files

Variations:

    Substitute the lowercase png in the command with any other format
    you want to convert your image to (your destination format). The
    directory pointed to in the -path switch must already exist. Otherwise,
    the command will fail. Depending on how many files you
    are processing, give the command at least a few seconds to 
    complete after calling it, before you go checking the destination
    directory for your converted files. The -path statement is
    optional, and may be omitted. If omitted, the *.png files will 
    be placed in the same directory as the original images.

    

You can also use any of the mogrify commands that we talked about earlier in the article. For some reason I can't figure out, the mogrify command will accept and work on multiple files passed from Thunar, while the convert command will not properly parse multiple filenames that are passed to it from Thunar. Instead, the convert command will use the last filename passed to it from Thunar, and append an incrementing number to the end of the filename.


Summary

As you can see, you can accomplish a lot of graphic manipulation tasks from Thunar's Custom Actions. Empowered by custom bash scripts, I'm sure there are many more graphic manipulations that can be done from a Thunar Custom Action.

The nice thing about being able to make these basic edits, en masse, from a Thunar Custom Action is that you can do them much quicker than if you opened the images in a graphics editor. As an exercise in furthering your knowledge of Thunar Custom Actions and working with graphics files, you might want to take a look at the command line tools aaphoto and rsvg.

You can make your custom actions as basic or fancy as you want. Of course, the fancier ones are most likely going to require a custom bash script. If you study the bash scripts, I think you will be able to see a skeleton framework that's common between the bash scripts we presented here. Simply perform the "meat" of your operations in the midst of the for loop. In the process, you'll gain a better understanding of bash programming.

If you come up with any innovative ImageMagick one-liners, I'd certainly be interested in hearing about them. Feel free to send me an email at pclinuxos.mag@gmail.com and tell me about them. I'll be happy to publish the one-liners in a future follow up article ... with due credit, of course.



Previous Page              Top              Next Page
Copyright (c) 2013, The PCLinuxOS Magazine. All Rights Reserved.