I have image files in a folder which may have different ways of spelling the extension (tiff, tif, TIF, gif, GIF etc.).
I want all images being converted to jpg
(via magick mogrify).
The un-converted image files should be deleted afterwards.
Everything needs to be done with a makefile.
My attempt so far:
RASTERFORMATS = tiff TIFF tif Tif TIf png PNG gif Gif
IMGPATH = workfiles/inserts/figures
figures2jpg: cleanfigures
cd $(IMGPATH) && \
for format in {$(RASTERFORMATS)} ;\
do \
magick mogrify -background white -flatten *.$$format ; \
magick mogrify -quiet -colorspace CMYK -format jpg *.$$format ; \
magick mogrify -quiet -colorspace CMYK -density 1200 -format jpg *.$$format ; \
done
rm $(IMGPATH)/*.{$(RASTERFORMATS)}
I would rather go with a separate rule for every file that needs to be converted as this helps in finding out whether there was an error or not and act accordingly. When doing everything in a loop like above a) any error is missed (and the source file gets deleted even when conversion failed) and b) it always regenerates all files no matter if it was needed or not.
My approach would be to get all the files with interesting extensions, generate target names and use a static pattern rule for each target file. I would also generate a warning if there are two or more input files that would result in the same target file as it was not clearly stated what should be done in this situation.
For example:
$ cat Makefile
RASTERFORMATS := [Pp][Nn][Gg] [GgTt][Ii][Ff]
IMGPATH := images
IMAGES_TO_CONVERT := $(foreach format,$(RASTERFORMATS),$(wildcard $(IMGPATH)/*.$(format)))
$(info Images to convert: $(IMAGES_TO_CONVERT))
IMAGES := $(sort $(addsuffix .jpg,$(basename $(IMAGES_TO_CONVERT))))
$(info Target images: $(IMAGES))
percent := %
.SECONDEXPANSION:
.DELETE_ON_ERROR:
$(IMAGES): %.jpg: $$(filter $$*$$(percent), $(IMAGES_TO_CONVERT))
$(if $(word 2,$^),$(warning Multiple sources for $@, generating from $<))
@echo "$< -> $@"
gm mogrify -background white -colorspace CMYK -density 1200 -format jpg $<
echo rm -f $< # Drop echo if really want to remove input file
.PHONY: figures2jpg
figures2jpg: $(IMAGES)
Given the following:
$ ls images/
image1.png image2.PNG image2.png image3.gif
Sample output is:
$ make figures2jpg
Images to convert: images/image2.png images/image2.PNG images/image1.png images/image3.gif
Target images: images/image1.jpg images/image2.jpg images/image3.jpg
images/image1.png -> images/image1.jpg
gm mogrify -background white -colorspace CMYK -density 1200 -format jpg images/image1.png
echo rm -f images/image1.png
rm -f images/image1.png
Makefile:16: Multiple sources for images/image2.jpg, generating from images/image2.png
images/image2.png -> images/image2.jpg
gm mogrify -background white -colorspace CMYK -density 1200 -format jpg images/image2.png
gm mogrify: Improper image header (images/image2.png).
Makefile:16: recipe for target 'images/image2.jpg' failed
make: *** [images/image2.jpg] Error 1
Note the warning for image2.jpg
. It also demonstrates that an error will prevent from deleting input file. Another invocation will retry, but image1.jpg
will not be generated again since it's already up to date.
$ make figures2jpg
Images to convert: images/image2.png images/image2.PNG images/image1.png images/image3.gif
Target images: images/image1.jpg images/image2.jpg images/image3.jpg
Makefile:16: Multiple sources for images/image2.jpg, generating from images/image2.png
images/image2.png -> images/image2.jpg
gm mogrify -background white -colorspace CMYK -density 1200 -format jpg images/image2.png
gm mogrify: Improper image header (images/image2.png).
Makefile:16: recipe for target 'images/image2.jpg' failed
make: *** [images/image2.jpg] Error 1