Wednesday, June 25, 2014

How to resize a picture using command-line tools

Occasionally, I need to resize an image. For instance, Google+ refuses to use my favorite portrait as my profile picture. The reason is that the portrait is smaller than the minimum requirement of 250 x 250 pixels.

To scale the image, I can opt for a GUI tool such as GIMP or Pinta. This post explores the scaling of pictures using command-line tools.

We will use tools such as convert and identify from the ImageMagick package. To install ImageMagick on Debian:

$ sudo apt-get update $ sudo apt-get install imagemagick

identify

To know the current dimension of the image, run the identify command:

$ identify portrait1.jpg portrait1.jpg JPEG 320x237 320x237+0+0 8-bit DirectClass 20.5KB 0.000u 0:00.000

The result includes the image width and height in the number of pixels (320x237). From that, we know that the image's height is below the minimum requirement.

convert

To scale the height dimension to 250 pixels:

$ convert -resize x250 -strip portrait1.jpg myProfile.jpg $ identify myProfile.jpg myProfile.jpg JPEG 338x250 338x250+0+0 8-bit DirectClass 35.2KB 0.000u 0:00.000

Note that the width is scaled up proportionally (to 338 pixels). To manually scale the width using convert, specify -resize 338x on the command line.

$ convert -resize 338x -strip portrait1.jpg myProfile1.jpg $ identify myProfile1.jpg myProfile1.jpg JPEG 338x250 338x250+0+0 8-bit DirectClass 35.2KB 0.000u 0:00.000

You can also use convert to dress up the picture, for instance, add a 3-pixel gray frame.

$ convert -resize x250 -strip -frame 3x3 -mattecolor "#999999" portrait1.jpg framedProfile.jpg

If optimizing file size is a major concern, you should investigate the use of the -quality option.

In general, image quality and file compression have an inverse relationship: higher image quality means lower file compression. The quality value ranges from 1 (lowest quality and highest compression) to 100 (highest quality but lowest compression).

$ convert -resize x250 -quality 95 -strip portrait1.jpg myProfile95.jpg $ $ ls -al myProfile*.jpg -rw-r--r-- 1 peter peter 19267 May 31 16:11 myProfile95.jpg -rw-r--r-- 1 peter peter 35160 May 31 15:31 myProfile.jpg

Specifying a quality of 95 (as compared to the default) resulted in a 45% reduction of the output file size. Some experimentation with quality values is needed to achieve the balance of minimal file size and acceptable image quality.

Tuesday, June 17, 2014

How to rename files in bulk

Consider this common scenario. A directory contains multiple files that are named using a common convention: for example, image-001.png, image-002.png, image-003.png, etc. You want to rename the files to, say, upload-001.png, upload-002.png, upload-003.png, etc.

The coders among us can write a bash script to automate the process. For expedience, this post shows how to use the built-in rename command to achieve the same goal.

The following command replaces the first occurrence of image with upload in the file name for all PNG files in the current directory.

$ rename -v 's/image/upload/' *.png image-001.png renamed as upload-001.png image-002.png renamed as upload-002.png image-003.png renamed as upload-003.png

Notes:

  • -v

    Produce verbose output, listing each file with its old and new names.

  • 's/image/upload/'

    Provide a valid PERL expression to modify the file names.

  • *.png

    Specify the files to be renamed.

The full power of PERL expressions is at your disposal to specify the file renaming rule. A thorough explanation of PERL expressions is beyond the scope of this post. The following only samples some useful PERL expressions.

  • Global replace.

    If you want to replace ALL occurrences of a pattern in a file name, you must specify a global replace. For example, you want to replace all spaces in the file names with null, that is, delete all spaces.

    $ rename -v 's/ //g' *.pdf Boarding Pass - Derek 2014-05-19.pdf renamed as BoardingPass-Derek2014-05-19.pdf Boarding Pass - Erin 2014-05-19.pdf renamed as BoardingPass-Erin2014-05-19.pdf capture_still_frame (1).pdf renamed as capture_still_frame(1).pdf capture_still_frame (2).pdf renamed as capture_still_frame(2).pdf
  • Match any character in a list.

    Suppose you want to replace all occurrences of spaces, underscores, and round brackets with the dash character. Here is how.

    $ rename -v 's/[_ ()]/-/g' *.pdf

    Any character within the square brackets is matched, and replaced by a dash.

  • Back reference variables.

    Suppose the file names follow this convention: prefix-sequence.suffix. For instance, usa-001.png. My task is to switch the order of the prefix and the sequence number, resulting in names such as 001-usa.png. You can achieve the result by using back reference variables as follows:

    $ rename -v 's/(.+)-([0-9]{3})/$2-$1/' *.png india-003.png renamed as 003-india.png uk-002.png renamed as 002-uk.png usa-001.png renamed as 001-usa.png

    The above example has 2 back reference variables separated by a dash: $1 and $2. The first variable $1 is defined by (.+), which means 1 or more characters. The second variable $2 is defined by ([0-9]{3}), which means exactly 3 digits, each digit being from 0 to 9. The replacement pattern, $2-$1, specifies that $2 now comes before $1, with a dash in between.

To avoid potential mistakes, you can first do a mock run of the rename command before actually running it for real. Specify the -n option, which stands for 'no-act'.

$ rename -n 's/image/upload/' *.png image-001.png renamed as upload-001.png image-002.png renamed as upload-002.png image-003.png renamed as upload-003.png

If all the suggested replacements look reasonable, then go ahead to run the command without the -n.

Monday, June 9, 2014

Create slide show from pictures - part 2 (GUI)

Part 1 of this series shows how to create a video or slide show from a set of image files using ffmpeg, a command-line tool. This post describes Imagination, a GUI-based tool, which offers some fancy animation features in slide show creation.

To install Imagination on a Debian Linux system:

$ apt-get install imagination

After installation, open Imagination, and follow the steps below to create a slide show:

  1. Create a new project.
    • Click New in the Slideshow menu.
    • Select the Video Format. Available video formats are VOB (DVD video), OGV, FLV (Flash video), and 3GP (for mobile phones). If you require something else (e.g., MP4, AVI), you can convert the video to such format later using ffmpeg.
      $ ffmpeg -i movie.vob -strict experimental movie.mp4
      
    • Select the Video Size. Various high definition, and standard definition sizes are available.
  2. Import the Pictures.
    • Click Import Pictures in the Slideshow menu.

      Note that the input picture files should reside in the same folder.

    • Navigate to the folder containing the picture files.
    • Multi-select the picture files.

      To multi-select, click the files while pressing the Ctrl or the Alt key.

  3. Rearrange (if so desired) the order of pictures to appear in the slide show.

    The thumbnails of the imported pictures are displayed horizontally at the bottom of the screen. The order in which the thumbnails are displayed is the same order they appear in the slide show. You can easily change the order by dragging and dropping the individual thumbnails.

  4. Select single or all pictures.

    You can configure individual slides, or you can apply the same property to multiple or even all slides. To select all slides, press the Ctrl-A keys. To select individual or to multi-set a subset of slides, click on the corresponding thumbnails.

  5. Modify Slide Settings.

    After selecting the slide(s) to work on, you are ready to make some changes. Minimally, you should change the Slide duration in sec. I modified the duration from 1 second (default) to 3 seconds.

    By default, there is no transition effect between slides (Transition Type is set to None). If you feel artistic, you can choose from a rich set of transition effects to assign to the slides. Click here for a live sample of all available transition effects.

  6. Add Slide Motion (Optional).

    You can apply the pan and zoom effect to a slide (aka the Ken Burns effect) by adjusting the Slide Motion properties.

    • Drag the Zoom slider to select the desired zoom level.
    • Pan the image by clicking and dragging the left mouse button until you are satisfied with the picture in view.
    • Set the duration for the slide motion.
    • Click Add to add a stop point.
    • Repeat the steps to add as many stop points as you want.
  7. Add Slide Text (Optional).

    You can add a subtitle to a slide by modifying the Slide Text properties.

    • Enter the subtitle text.
    • Adjust the font, including its size, and color.
    • Select the subtitle position.
  8. Add a sound track (Optional).

    Click Import music in the Slideshow menu, and select the music file.

    Once imported, the music file is listed in the Audio tab with its duration in clear display. Note: if the audio duration is longer than that of the video, the audio and ultimately the slide show stop when the video stops. The video does not loop back.

  9. Export slideshow.
    • Click Export in the Slideshow menu.
    • Enter the output file name including the extension (e.g., fashion.vob).
    • Select the aspect ratio: 4:3 versus 16:9.

    The slide show is created in the video format specified earlier when you created the project (e.g., .vob).

Sunday, June 1, 2014

Create slide show from pictures - part 1

After you upload your pictures from your digital camera to your Linux computer, you want to view them without having to manually open each one. This post explains how to create a slide show from a set of picture files using ffmpeg, a command-line tool. My next post turns to Imagination, a GUI-based tool, to achieve the same goal.

To create a video from still images,

$ ffmpeg -r 1/3 -i image-%03d.png -vcodec copy out.mp4

Notes:

  • Order matters

    In general, options are applied to the next specified file on the command line. For instance, the -r (aka, frame rate) option applies to the PNG files, not the MP4 file. The order of specifying options is important for ffmpeg.

  • -r

    This is the frame rate specified in frames per second. The default is 25 which is too fast for human consumption. For a quick view of a large number of pictures, I prefer 3 seconds per frame, or 1/3 frame per second, hence -r 1/3.

  • -i

    The input picture files must be sequentially numbered, starting with the number 1. The image-%03d.png pattern matches files image-001.png, image-002.png, etc.

    The input files must share the same size (e.g., 1280 x 720 pixels) and format (e.g., PNG).

  • -vcodec copy

    The video input stream will be copied as is to the output file. Without this parameter, I found that the last picture file is omitted from the output video.

A slide show can be quite bland without background music. You can enhance the slide show by adding an audio stream from a sound file using the following command:

$ ffmpeg -r 1/3 -i image-%03d.png -i music.mp3 -vcodec copy -strict experimental out.mp4

Notes:

  • -i

    The video file (PNG) and the audio file (MP3) are specified.

  • -strict experimental

    This option is required because the default AAC audio encoder is experimental in ffmpeg.

Ideally, the duration of both the video and audio input files is the same. Otherwise, you may be staring at the video with no background music, or listening to the music while the video is stuck at the last frame. The simplest solution is to add the -shortest option.

The -shortest option guarantees that the length of the output video does not exceed that of the shortest input stream, audio or video. Therefore, when the video stops, so does the audio, and vice versa.

$ ffmpeg -r 1/3 -i image-%03d.png -i music.mp3 -vcodec copy -strict experimental -shortest out.mp4

If your audio is longer than the video, you can enable video looping by specifying -loop 1. The net effect is that the video will restart at the beginning if it finishes before the audio does.

$ ffmpeg -loop 1 -r 1/3 -i image-%03d.png -i music.mp3 -vcodec copy -shortest -strict experimental out.mp4

Note that -loop applies to video looping only. The audio track is not looped if it finishes before the video.

Using ffmpeg, you can create a basic, no-thrill slide show from your still pictures. If you want to add animation effect while transitioning from 1 slide to the next, please see my next post on the Imagination GUI tool.

If you are interested in what else you can do with ffmpeg, please read my earlier post on Capturing video snapshots.