ImageMagick: how to batch combine multiple TIFF file to a single TIFF file in a directory? - imagemagick

I have 600 TIFF files in a directory, c:\temp.
The file names are like:
001_1.tif,
001_2.tif,
001_3.tif
002_1.tif,
002_2.tif,
002_3.tif
....
....
200_1.tif,
200_2.tif,
200_3.tif
The combined files should be placed in same directory and the files should be named like:
1_merged.tif
2_merged.tif
.....
.....
200_merged.tif
I am looking for any single command-line /batch-file to do so through ImageMagick convert/ mogrify command or any other command/tools.
Please note the overall time taken should not be more than 5 second.

Assuming you want to combine the 600 single-page TIFFs into one single multi-page TIFF (per set of 3), it is as simple as:
convert 001_*.tiff 1_merged.tiff
convert 002_*.tiff 2_merged.tiff
[....]
convert 200_*.tiff 200_merged.tiff
Please note that nobody will be able to guarantee any timing/performance benchmarks... least while we don't even have any idea how exactly your input TIFFs are constituted. (Are they 10000x10000 pixels or are they 20x20 pixels?, Are they color or grayscale?, etc.pp.)
This is different from Mark's answer, because he seems to have assumed you want to combine the input files all into a 1-page image, where the originals are tiled across a larger page...

This should do it - I will leave you to do error checking in case you haven't actually got all the images you suggest!
#ECHO OFF
setlocal EnableDelayedExpansion
FOR /L %%A IN (1,1,200) DO (
set "formattedValue=000000%%A"
set "x=!formattedValue:~-3!"
convert !x!_*.tif +append !x!_merged.tif
echo !x!
)
So, if your images look like this
001_1.tif
001_2.tif
001_3.tif
you will get this in merged_001.tif
If you change +append to -append then merged_001.tif will be like this:
If you remove +append altogether, you will get 200 multi-page TIFs with 3 pages each - same as Kurt's answer.

Related

How can I merge images from two folders into a together side-by-side with imagemagick?

I have two folders, A and B, with image files that have corresponding names.
For example, each contain files labelled 01.png, 02.png, 03.png, etc.
How can I merge the corresponding files such that I have a third folder C that contains all merged photos so that both of the originals are side by side.
I am on Linux, if that changes anything.
I am not near a computer to thoroughly test, but this seems easiest to me:
#!/bin/bash
# Goto directory A
cd A
# For each file "f" in A
for f in *.png; do
# Append corresponding file from B and write to AB
convert "$f" ../B/"$f" +append ../AB/"$f"
done
Or use GNU Parallel and do them all at once!
cd A
parallel convert {} ../B/{} +append AB/{} ::: *.png
Using ImageMagick version 6, if your images are all the same dimensions, and if your system memory can handle reading all the input images into a single command, you can do that with a command like this...
convert FolderA/*.jpg -set filename:f "%[f]" \
-set option:distort:viewport %[fx:w*2] -distort SRT 0 null: \
FolderB/*.jpg -gravity east -layers composite FolderC/"%[filename:f]"
That starts by reading in all the images from FolderA and extending their viewport to double their width to the right.
Then it adds the special built-in "null:" to separate the lists of images before reading in the second list. Then it reads in all the images from FolderB.
Then after setting the gravity to "east", it composites each image from FolderB over the extended right half of each corresponding image from FolderA. That creates the effect of appending the images side by side.
The command sets a variable at the beginning to hold the filenames of the first list of input files, then uses those as the names of the output files and writes them to FolderC.
If you're using ImageMagick version 7, use the command "magick" instead of "convert".
You can do that with some bash scripting code. Assume you have two folders A and B with the corresponding image names in them. Also you have an empty folder AB to hold the results. Then using ImageMagick with the bash looping code, you can do something like this:
Collect the names of all the files in folder A and put into an array
Collect the names of all the files in folder B and put into an array
Loop over the number of images in the folders
Process them with ImageMagick +append and save to folder AB
outdir="/Users/fred/desktop/AB"
aArr=(`find /Users/fred/desktop/A -type f -iname "*.jpg" -o -iname "*.png"`)
numA="${#aArr[*]}"
bArr=(`find /Users/fred/desktop/B -type f -iname "*.jpg" -o -iname "*.png"`)
numB="${#bArr[*]}"
if [ $numA -eq $numB ]; then
for ((i=0; i<numA; i++)); do
nameA=`basename "${aArr[$i]}"`
nameA=`convert "$nameA" -format "%t" info:`
nameB=`basename "${bArr[$i]}"`
nameB=`convert "$nameB" -format "%t" info:`
convert "${aArr[$i]}" "${aArr[$i]}" +append ${outdir}/${nameA}_${nameB}.jpg
done
fi

Combine multiple images with same name

I have a folder called "Images" and one called "Mask". In the "Image" folder there are 200 images and in the "Mask" folder there are 200 images (with transparent background) with the same name. I now want to combine always the two pictures with the same name, so the image form the "Image" folder is in the background. The image are the same size.
Example Background image:
Example Mask:
I guess it should be quite easily doable with imagemagick, but i don't really now this program and the examples I found are all way more sophisticated.
I tried something like that:
convert Images/*.png -draw "image over x,y 0,0 Mask/*.png" combined/*.png
Did it not work because of the path? Do I have to to a loop, or is there a easy way?
Thanks
As you have lots of images, and it will do all the loops and filename/directory splitting for you, I would use GNU Parallel like this:
mkdir -p combined
parallel 'convert {} Mask/{/} -composite combined/{/}' ::: Images/*png
Be very careful with parallel and test what you plan to do with:
parallel --dry-run ...
first to be sure.
{} means "the current parameter"
{/} means "the current parameter stripped of the directory part"
::: indicates the start of the parameters.
Or, you can use a loop like this:
#!/bin/bash
mkdir -p combined
cd Images
for f in *png; do
convert "$f" ../Mask/"$f" -composite ../combined/"$f"
done
I finally find a way with a small bash script:
#!/bin/bash
for entry in Images/*
do
name="$(cut -d'/' -f2 <<<"$entry")"
convert Cells/$name Mask/$name -composite combined/$name
done

Capture information on images generated by ImageMagick

I'm considering using ImageMagick to extract images from individual pages from a PDF file. How can I capture the names of the files getting generated by it? It seems that the -verbose option includes information on the files getting generated, but is that a reliable way of gathering that? Any other alternatives?
Depending on what you want to do, I think you have at least 3 options...
Option 1
If you want to know the number of pages up front, a priori, you can get ImageMagick to tell you like this:
identify -format %n FreddyFrog.pdf
8
or if you want it in a variable,
pages=$(identify -format %n FreddyFrog.pdf)
echo $pages
8
Option 2
You can tell ImageMagick how to format the names of the output files, like this, where the %04d says to use 4 digits and front-pad with zeroes:
convert -density 72 FreddyFrog.pdf FreddyFrog-%04d.tif
Then you will automatically know the names of the output files.
ls FreddyFrog-*
FreddyFrog-0000.tif FreddyFrog-0003.tif FreddyFrog-0006.tif
FreddyFrog-0001.tif FreddyFrog-0004.tif FreddyFrog-0007.tif
FreddyFrog-0002.tif FreddyFrog-0005.tif
Option 3
You can use the shell to draw a line in the sand before you convert the files and then find everything newer afterwards:
> before # or "touch before" if you prefer
convert FreddyFrog..... # strut your IM stuff
for f in *; do [[ "$f" -nt before ]] && echo $f; done # list files newer than line in sand
rm before # clean up
rm before

ImageMagick thumbnail Batch processing on Windows

I am using ImageMagick to create thumbnails of photos.
I am using windows OS.
My source files are contained in numerous sub folders.
I wish to make thumbnails of the source files by saving to a destination folder on a different drive while preserving the same folder structure and modifying the original filename.
The destination file name is the same as the source but with 1 character modified:
Source examples:
c:\images\1\1L0000021.jpg
c:\images\1\1L000561.jpg
c:\images\2\234L0000032.jpg
c:\images\3\31214L000001.jpg
To dest drive:
d:\images\1\1M0000021.jpg
d:\images\1\1M000561.jpg
d:\images\2\234M0000032.jpg
d:\images\3\31214M000001.jpg
Note: only one letter need be changed from L to M
The source filename pattern is always: *l*.jpg
Here is the command I want to run to do the image processing:
convert -thumbnail 200x220^^ -gravity center -extent 200x200 -quality 80 c:\images\*.jpeg d:\images\output.jpeg
The above command creates the desired thumbnails from the source folder and saves into the destination folder but the output filename is incorrect and it does not traverse sub folders.
Questions:
1) how to traverse each folder and subfolder and then output to the exact same structure on the destination drive (create the folders if they don't exist)
2) how to modify the output filename so that *l*.jpeg becomes *m*.jpeg
UPDATE
Here is my final code in case it helps anybody in the future:
::You must first install ImageMagick
::This job converts large photos into 200x200 thumbnails and saves the new files to the specified destination.
#echo off
setlocal enabledelayedexpansion
SET "#SOURCE=C:\Test\photos\"
SET "#DEST=C:\dest"
REM Replicate source folder structure to destination:
for /r %#SOURCE% %%D in (.) do (
echo Creating folder: %#DEST%%%~pnxD
#md "%#DEST%%%~pnxD"
)
REM Select images from source using wildcard:
for /r %#SOURCE% %%F in (*l*.jpeg) do (
REM Modify file name (i'm replacing 'l' for 'm')
set "fname=%%~nF"
set "fname=!fname:l=m!"
REM Convert source image to thumbnail and save to destination:
REM echo Source: %%F
echo Saving: %#DEST%%%~pnxF
#convert -thumbnail 200x220^^^^ -gravity center -extent 200x200 -quality 80 "%%F" "%#DEST%%%~pF!fname!%%~xF"
)
1) this is how you duplicate a folder tree from C:\source to X:\dest:
for /r C:\source %I in (.) do #md "X:\dest%~pnxI"
What this for loop does is traverse a folder tree, starting at C:\source, with each folder name in the variable %I. The command "md" is short for "mkdir". The modifiers "~pnx" strip off the original drive letter, so that X:\dest can be prepended.
NOTE that there is no backslash after "X:\dest" as the first backslash of the original path is preserved.
2) Use the same command to run the Imagick command to process your JPEG files:
for /r C:\source %I in (.) do #convert -options %I "X:\dest%~pnxI"
The target name is identical.
3) Rename all JPEGs in the destination tree using the FlexibleRenamer tool by Naru (http://hp.vector.co.jp/authors/VA014830/english/FlexRena/). It can use a Regular Expression to select and modify names.
You would rename
"(\d+)L(.+)"
to
"\1M\2"
meaning: at least one decimal, followed by an literal "L", followed by at least one more character. The name is replaced by the first part, a literal "M" and the second part.
edit:
The processing step 2) needs a file selector to work, like this:
for /r C:\source %I in (*.jpg) do #convert -options %I "X:\dest%~pnxI"
Otherwise, only folder names are processed - which may or may not suffice depending on the 'convert' program.
Try this:
#echo off &setlocal enabledelayedexpansion
for /r "c:\images" %%a in (*.jpg) do (
set "fname=%%~na"
set "fname=!fname:L=M!"
md "D:%%~pa" 2>nul
convert -thumbnail 200x220^^ -gravity center -extent 200x200 -quality 80 "%%~fa" "D:%%~da!fname!%%~xa"
)

ImageMagick pdf to black and white pdf

I would like to convert a pdf file to a Black and White PDF file with ImageMagick. But I've got two problems:
I use this command:
convert -colorspace Gray D:\in.pdf D:\out.pdf
But this command convert only the FIRST page... How to convert all pages?
After use this command the resolution is terrible... but if I use -density 300 option the file size has increased more than double. So I would like to use the same DPI setting, but how to use?
Thanks a lot
Assuming you have all the necessary command line tools installed you can do the following:
Split and join PDF using pdfseparate and pdfunite (Poppler tools).
Extract the original density using pdfinfo plus grep/egrep and, for instance, sed. This will not guarantee the same size of the PDF file, just the same DPI.
Putting it all together you can have a series of bash commands as following:
pdfseparate in.pdf temp-%d.pdf; for i in $(seq $(ls -1 temp-*.pdf | wc -l)); do mv temp-$i.pdf temp-$(printf %03d $i).pdf; done
for f in temp-*.pdf; do convert -density $(pdfinfo $f | egrep -o 'Page size:[[:space:]]*[0-9]+(\.[0-9]+)?[[:space:]]*x[[:space:]]*[0-9]+(\.[0-9]+)?' | sed -e 's/^Page size:\s*//'| sed -e 's/\s*x\s*/x/') -colorspace Gray {,bw-}$f; done
pdfunite bw-temp-*.pdf out.pdf
rm {bw-,}temp-*.pdf
Note 1: there as a dirty workaround (for/wc/seq/printf) for a proper ordering of 10-999 pages PDFs (I did not figure out how to put leading zeros in pdfseparate).
Note 2: I guess ImageMagick treats PDFs as just another binary image file so for instance for mainly text files this will result in huge PDFs. Thus, this is a very bad method to convert text-based PDFs to B&W.

Resources