How can I split images based on these divider lines using [ImageMagick?]
Arguably, the simplest solution would likely be to use -crop like so:
convert -crop 3x2@ -scene 1 image1.jpg image2.jpg cropped_%02d.jpg
Divides each image into 6 (roughly) equal size tiles (-crop 3x2@), numbering each one in order.
Starts the numbering sequence at
1 (-scene 1), rather than
Gives the final numbers a
%02d) in the single digits [
While it is possible to specify an exact size (e.g.
1000x1000) or use percentages (e.g.
33%x50%) for a tile crop, this can potentially produce "trimming" images as well (likely undesirable).
-3x2@ typically creates images that are closer in size (relative to each other) than "overshooting" percentages (e.g
33.4%x50%) to avoid producing "trimming" images.
In a batch file, you'll need to double the percent signs to have them work as intended:
convert -crop 3x2@ -scene 1 image1.jpg image2.jpg cropped_%%02d.jpg
If you are writing to formats that can have image/canvas offsets (e.g.
.png), you may wish to include +repage after your
convert -crop 3x2@ +repage -scene 1 image1.jpg image2.jpg cropped_%02d.png
If your input formats can contain image/canvas offsets, you may want to
+repage those as well.
Is it possible to automatically number them based on the order described above?
With ImageMagick alone, I was unable to do so (I suspect it likely isn't possible, but I honestly am not certain about this). Of course, separate from ImageMagick, this is completely possible.
Since you have tagged this question with
batch, its worth mentioning I probably can't help with any good solutions in batch. With that in mind, it seems very likely you (or someone else) might be able to come up with something better than what I detail below.
Obligatory Batch (Non-)Answer
Renaming by brute force is possible with batch. First, rename every file (except the first and last) temporarily e.g.:
rename cropped_02.jpg cropped_02_temp.jpg
rename cropped_11.jpg cropped_11_temp.jpg
Then rename them back to their new positions e.g.:
rename cropped_02_temp.jpg cropped_03.jpg
rename cropped_03_temp.jpg cropped_05.jpg
rename cropped_04_temp.jpg cropped_07.jpg
rename cropped_05_temp.jpg cropped_09.jpg
rename cropped_06_temp.jpg cropped_11.jpg
rename cropped_07_temp.jpg cropped_02.jpg
rename cropped_08_temp.jpg cropped_04.jpg
rename cropped_09_temp.jpg cropped_06.jpg
rename cropped_10_temp.jpg cropped_08.jpg
rename cropped_11_temp.jpg cropped_10.jpg
Batch has the ability to take arguments from the command line and do math, as well as possessing
for loops and
if statements, etc. so this solution can (obviously) be improved upon.
If you look at the second half of the renaming process above, you'll notice a pattern in the file names. Effectively, for a given Position N, we can use one of the following two formulas to find an item's new position in your scheme:
- Items up to the "halfway" point (e.g. 2-6) :
(Position_N * 2) - 1
- Items beyond the "halfway" point (e.g. 7-11):
(Position_N * 2) - Total_Items
Note: While it is possible to apply these formulas to an entire sequence (e.g. 1 and 12), the first and last items never change positions. This arguably makes renaming them unnecessary.
Furthermore, these should work for any even (not odd) number of items/positions (4 or greater), assuming your file names are in order (e.g. 1 to 12). So for your original examples:
Temp Item 2 becomes (2 * 2) - 1 = Item 3
Temp Item 7 becomes (7 * 2) - 12 = Item 2
Temp Item 8 becomes (8 * 2) - 12 = Item 4
Thus, the formulas given can potentially be the basis for batch (or other scripting) solutions. However, there are a couple of other things to be aware of if you decide to use them as such...
Sorting (as alluded to above) can have practical consequences in things like scripts, as items returned "out of order" by Windows will "break" the formulas given. Particularly:
Windows sorts names in lexicographical order by default. This means items that don't have a
0 in front of single digits (e.g. image_1.jpg vs. image_01.jpg) won't appear in (natural) order when returned directly by Windows. That is, they will be returned as e.g.:
cropped_1.jpg, cropped_10.jpg, cropped_11.jpg, cropped_12.jpg, cropped_2.jpg, etc.
Certain words and phrases (such as
- Copy) in file names can also affect the order in which file names are returned.
If you use the formulas above, make sure to
0-pad single digits in your file names and remove things like
- Copy (or otherwise take steps to mitigate these issues).
Loops/Counters Starting With 0
If you are using a language that starts counting with
0 (for instance, in loops), then this can change the formulas slightly:
- Items up to the "halfway" point (e.g. 1-5) :
(Position_N * 2)
- Items beyond the "halfway" point (e.g. 6-10):
(Position_N * 2) - (Total_Items - 1)
Remember that, counting from 0, 12 items would run
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11.
A Python Script
If you are interested, I have written a small, (likely terrible) Python script for Python 3.x (tested with 3.6.4), which can be used from the command line to rename arbitrary files which are in sequence (e.g. cropped_01.jpg ... cropped_XX.jpg) to the order specified in your question. You will need to have a copy of Python installed if you decide to try it out.
Doesn't read from text files for information (so no specifying a list of files at this time). Likewise, an image/file name prefix and extension are required at the command line.
As is, the script expects file names to be returned in the correct order automatically (see Windows and
There is an option to use a third-party module called
natsort (installed with e.g.
python -m pip install natsort) if your items are not
0-padded. However, you need to uncomment line 13 (
from natsort import natsorted) and line 105 (
item_list = list(natsorted(item_list))) in the script after installing
natsort to use this option.
To be clear, "uncomment" means remove the
# and leading space at the beginning of the line. Additional instructions on usage are included with the script.