Convert HEIC photos to JPEG

A quick note-to-self about how I managed to download a bunch of photos from an iPhone and convert them to JPEG on my laptop running Ubuntu 22.04.

As opposed to Android phones, iPhones do not show up as a regular disk with easy access to the DCIM folder storing photos. Fortunately, Rapid Photo Downloader managed to launch the iPhone and find all the images. Unfortunately, all the files were stored as HEIC files, using the High Efficiency Image File Format. This format is technically good but practically tricky to work with. So I wanted to convert the files to JPEG.

With some searching, I got some help with How to Open or Convert iOS HEIC Photos to JPEG and PNG in Ubuntu 20.04 | 22.04. The trick is to install a small collection of tools for working with HEIF files:

sudo apt-get install libheif-examples

Then I ran this one-liner to convert a folder of HEIC files:

for file in *.heic; do heif-convert $file ${file/%.heic/.jpg}; done

That’s it!

Convert a folder of LibreOffice .ODT files to .DOCX files

I don’t spend much time in traditional “word processors”, but when I do, it is usually in LibreOffice. Then I prefer to save the files in the native .ODT format. But it happens that I need to send a bunch of files to someone that prefers .DOCX files. Instead of manually converting all the files, here is a short one-liner that does the trick using the magical pandoc, the go-to tool for converting text documents.

for i in *.odt; do name=`echo $i | cut -d'.' -f1`; pandoc "$i" -o "${name}.docx"; done

Paste it into a terminal window opened in the directory of choice and watch the magic!

Add fade-in and fade-out programmatically with FFmpeg

There is always a need to add fade-in and fade-out to audio tracks. Here is a way of doing it for a bunch of video files. It may come in handy with the audio normalization script I have shown previously. That script is based on continuously normalizing the audio, which may result in some noise in the beginning and end (because there is little/no sound in those parts, hence they are normalized more).

It is easy to add a fade-in to the beginning of a file using FFmpeg’s afade function. From the documentation, you can do a 15-second fade-in like this:

afade=t=in:ss=0:d=15

And a 25-second fade-out like this:

afade=t=out:st=875:d=25

Unfortunately, the latter requires that you specify when to start the fade-out. That doesn’t work well in general, and particularly not for batch processing.

A neat trick

Searching for solutions, I found a neat trick that solved the problem. First, you create the normal fade-in. Then you make the fade-out by reversing the audio stream, applying a fade-in, and then reversing again. The whole thing looks like this:

ffmpeg -i input.mp4 -c:v copy -af "afade=d=5, areverse, afade=d=5, areverse" output.mp4

A hack, but it works like a charm! And you don’t need to re-encode the video (hence the -c:v copy message above).

Putting it together

If you want to run this on a folder of files and run a normalization in the same go (so you avoid recompressing more than once), then you can use this bash script:

#!/bin/bash

shopt -s nullglob
for i in *.mp4 *.MP4 *.mov *.MOV *.flv *.webm *.m4v; do 
   name=`echo $i | cut -d'.' -f1`; 
   ffmpeg -i "$i" -c:v copy -af "loudnorm=I=-16:LRA=11:TP=-1.5,afade=d=5, areverse, afade=d=5, areverse" "${name}_norm.mp4"; 
done

Save, run, and watch the magic!

Export images from a PDF file

I have previously written about how to export each of the pages of a PDF file as an image. That works well for, for example, presentation slides that should go on a web page. But sometimes there is a need to export only the images within a page. This can be achieved with a small command line tool called pdfimages.

One way of using it is:

pdfimages -p -png file.pdf image

This will export all images in file.pdf and label them with something like image-001-010.png, where the first number refers to the page and the second is a count of images.

Sometimes I just take a screenshot if I want to grab something from a PDF. But this is a more robust method if you want to grab several different images from a PDF file.

Programmatically resizing a folder of images

This is a note to self about how to programmatically resize and crop many images using ImageMagick.

It all started with a folder full of photos with different pixel sizes and ratios. That is because they had been captured with various cameras and had also been manually cropped. This could be verified by running this command to print their pixel sizes:

identify -format "%wx%h\n" *.JPG

Fortunately, all the images had a reasonably large pixel count, so I decided to go for a 5MP pixel count (2560×1920 in 4:3 ratio). That was achieved with this one-liner:

for i in *.JPG; do convert "$i" -resize 3000x1920 -crop 2560x1920+0+0 "$i"; done

The little script looks for all the image files in the folder and starts by resizing them to the preferred height (1920 pixels) and then cropping them to the correct width (2560 pixels). The result is a folder full of equally sized images.

Ps: the script above overwrites the original files in the folder.