0

I'm trying to blur the bottom section of thousands (>50,000) of images using imagemagick. Image resolution is 800x600. The command line code (below) works, but takes a long time. Is there any way that this can be run in parallel, and hopefully called from within R using system()?

I got this code off the internet, so I'm not sure if it's the best way to even achieve this objective? Any help would be greatly appreciated. Thanks in advance!

(OS = OSX El Capitan)

cd /Users/Desktop/test_images list=$(ls *.jpg) for img in $list; do convert $img \ \( -size 800x525 xc:black -size 800x75 xc:white -append \) \ -compose blur -define compose:args=6 -composite \ cd /Users/Desktop/test_images/results/$img done cd 
5
  • Have a look at this Entry about running parallel jobs and waiting for them to finish with bash. You could rewrite your script such that it starts #cpu jobs (or #cpu+1) and waits until they finish. If the jobs workload is evenly distributed, chance is high that it will give a good speedup. That would be pure bash thought and not flexible if you want to run it on other systems with more/less cores. Commented Oct 14, 2016 at 14:21
  • Please provide a sample image of the correct dimensions and also another showing the expected result. Commented Oct 14, 2016 at 14:29
  • @Mark Setchell - an original sample image can be downloaded here (dropbox.com/sh/3bnwmnklslo2shu/AABxDW-MeyAmBzspiSiV6HmFa?dl=0), and the blurred result here (dropbox.com/sh/uwadeuc7rohq1d7/AAAbT79z2f34O4z8hKv1jqbWa?dl=0). Commented Oct 14, 2016 at 14:57
  • you don't need to run a system command with the new magick package. Try that with R parallel ops. Commented Oct 14, 2016 at 15:15
  • Thanks @hrbrmstr. I didn't realise there was a magick package, very happy about this! I'll have a look at this asap, but for now, Mark's solution is fantastic. Thanks again! Commented Oct 14, 2016 at 15:56

1 Answer 1

2

I think this command does something very similar to what you are doing but is FAR quicker. See if you like the effect:

convert start.jpg \( +clone -crop +0+525 -blur x4 \) -gravity south -composite result.jpg 

enter image description here

If that works, you can use GNU Parallel just as before:

parallel 'convert {} \( +clone -crop +0+525 -blur x4 \) -gravity south -composite results/{}' ::: *.jpg 

You can also put that lot in a script called BlurTitle like this:

#!/bin/bash parallel 'convert {} \( +clone -crop +0+525 -blur x4 \) -gravity south -composite results/{}' ::: *.jpg 

and then make it executable with:

chmod +x BlurTitle 

and call it from R with:

system("./BlurTitle") 

or from the Terminal with:

./BlurTitle 

If you get "Argument list too long", you can express it the other way around like this by sending the arguments on stdin rather than after the command:

cd /path/to/images find . -name \*.jpg -print0 | parallel -0 'convert {} \( +clone -crop +0+525 -blur x4 \) -gravity south -composite results/{}' 
Sign up to request clarification or add additional context in comments.

3 Comments

Brilliant solution. It's extremely fast. Thanks so much!
For others who may find this useful, Mark's GNU Parallel reference refers to a similar post, which can be accessed here: stackoverflow.com/questions/40035067/…
there appears to be a limit to the number of images this code will work on. I've just attempted it with 29,000 images and I get the following error: -bash: /usr/local/bin/parallel: Argument list too long

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.