There are some scanned image files. The scan is made larger than the actual content, such that white borders are shown in the image files. I would like to (use ImageMagick to auto detect and) trim the borders, while not trimming so hard (in case the content background is white also) by keeping a minimum size of the image.
Same question has been asked about a year ago: ImageMagick: trim but keep a minimum size. I guess the trim:minSize=geometry were not available at that moment.
Documentations are here:
https://imagemagick.org/script/command-line-options.php#trim
-trim
...
Use -define trim:minSize=geometry limit the trim to the specified size.
https://imagemagick.org/script/command-line-options.php#define
-define key{=value}...
https://imagemagick.org/script/defines.php
trim:minSize=geometry
Limit the trim to the specified size.
Previous discussion for adding the trim:minSize feature: https://github.com/ImageMagick/ImageMagick/discussions/4861?sort=new.
My trial:
# magick -verbose input.tif -fuzz 5% -define trim:minSize=2310x2600 -trim output.tif
input.tif TIFF 2368x2633 2368x2633+0+0 8-bit TrueColor sRGB 16.915MiB 0.020u 0:00.025
input.tif=>output.tif TIFF 2368x2633=>2301x2586 2368x2633+67+0 8-bit TrueColor sRGB 17.0247MiB 0.020u 0:00.022
input.tif is a scanned image of 2368x2633px with white borders.
The above command output is trimmed to 2301x2586px, which is not respecting the trim:minSize=2310x2600 constrain.
FYI: The solution in the linked question is adding a border after the trim, which is not ideal. If the content is close to white but not white, it will be trimmed then a white border is added.
Is it that I wrongly used the magick command or parameters, or ImageMagick trim:minSize definition is really not working?
Edit:
More information about the question.
I just updated ImageMagick to version 7.1.0-48 on Gentoo Linux.
# magick -version
Version: ImageMagick 7.1.0-48 Q16 x86_64 20449 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenCL OpenMP(4.5)
Delegates (built-in): bzlib cairo freetype jng jpeg lcms ltdl pangocairo png rsvg tiff x xml zlib
Compiler: gcc (11.3)
The original tiff image I was working on is too large (17MB) for testing and upload. I downsized it to the following 719x800px smaller png. There are still weird results with it.
First, try basic trim. It trimmed to 676x784px.
# magick -verbose input.png -fuzz 15% -trim output.png
input.png PNG 719x800 719x800+0+0 8-bit sRGB 805860B 0.010u 0:00.011
input.png=>output.png PNG 719x800=>676x784 719x800+29+2 8-bit sRGB 805860B 0.210u 0:00.191
Then use -define trim:minSize=710x799 to limit the trim. It trimmed to 707x798px, which is smaller than the minSize.
# magick -verbose input.png -define trim:minSize=710x799 -gravity south -fuzz 15% -trim output.png
input.png PNG 719x800 719x800+0+0 8-bit sRGB 805860B 0.010u 0:00.010
input.png=>output.png PNG 719x800=>707x798 719x800+12+2 8-bit sRGB 805860B 0.220u 0:00.198
If we omit the -gravity south. It even trims to 690x798px, much smaller than the minSize.
# magick -verbose input.png -define trim:minSize=710x799 -fuzz 15% -trim output.png
input.png PNG 719x800 719x800+0+0 8-bit sRGB 805860B 0.010u 0:00.010
input.png=>output.png PNG 719x800=>690x798 719x800+29+2 8-bit sRGB 805860B 0.220u 0:00.193
I am not sure how to use the +gravity and +repage to reset the gravity and virtual canvas. It seems they do not help. In both cases, it still trims to 690x798px.
# magick -verbose input.png -define trim:minSize=710x799 +gravity -fuzz 15% -trim output.png
input.png PNG 719x800 719x800+0+0 8-bit sRGB 805860B 0.010u 0:00.011
input.png=>output.png PNG 719x800=>690x798 719x800+29+2 8-bit sRGB 805860B 0.220u 0:00.192
# magick -verbose input.png +repage -define trim:minSize=710x799 -fuzz 15% -trim output.png
input.png PNG 719x800 719x800+0+0 8-bit sRGB 805860B 0.010u 0:00.010
input.png=>output.png PNG 719x800=>690x798 719x800+29+2 8-bit sRGB 805860B 0.220u 0:00.199
I am not sure if it is legit to use -gravity in combination with -define trim:edges. I find weird result from fmw42's sample picture also. (fmw42's sample picture is more trivial that its border is absolutely blue. It does not need -fuzz.)
# magick -verbose lena_b50.png -define trim:minSize=300x300 -gravity south -define trim:edges=east,south,west -trim lena_b50_trim.png
lena_b50.png PNG 356x356 356x356+0+0 8-bit sRGB 121273B 0.000u 0:00.002
lena_b50.png=>lena_b50_trim.png PNG 356x356=>256x306 356x356+50+0 8-bit sRGB 121273B 0.030u 0:00.025
Lexically this makes sense. -gravity south aligns the content to top. -define trim:edges=east,south,west avoids trimming the north edge.
Note it is trimmed to 256x306px, smaller than minSize of 300x300px.
Trim edges east,south,west with minSize is 330x330px.
It produces 306x330px result, with strange alignment.
# magick -verbose lena_b50.png -define trim:edges=east,south,west -define trim:minSize=330x330 -trim lena_b50_trim.png
lena_b50.png PNG 356x356 356x356+0+0 8-bit sRGB 121273B 0.000u 0:00.002
lena_b50.png=>lena_b50_trim.png PNG 356x356=>306x330 356x356+50+0 8-bit sRGB 121273B 0.040u 0:00.027
With east,south,west and 330x330, add also -gravity south. It produces reasonable result.
# magick -verbose lena_b50.png -define trim:edges=east,south,west -define trim:minSize=330x330 -gravity south -trim lena_b50_trim.png
lena_b50.png PNG 356x356 356x356+0+0 8-bit sRGB 121273B 0.000u 0:00.002
lena_b50.png=>lena_b50_trim.png PNG 356x356=>330x330 356x356+13+0 8-bit sRGB 121273B 0.040u 0:00.025
Yet if the minSize is smaller (300x300px). It fails again. Result image is 256x306px.
# magick -verbose lena_b50.png -define trim:edges=east,south,west -define trim:minSize=300x300 -gravity south -trim lena_b50_trim.png
lena_b50.png PNG 356x356 356x356+0+0 8-bit sRGB 121273B 0.000u 0:00.001
lena_b50.png=>lena_b50_trim.png PNG 356x356=>256x306 356x356+50+0 8-bit sRGB 121273B 0.030u 0:00.026
It works fine for me on Imagemagick 7.1.0.57 Q16 Mac OSX Monterey.
Input (size 356x356):
magick lena_b50.png -define trim:minSize=300x300 -gravity center -trim lena_b50_trim.png
Result (size 300x300)
ADDITIONI
The minSize define is a relatively new feature (7.1.0.30 and higher). So it was not implemented in your older version of Imagemagick 7.
Also one may need to add -fuzz XX% to the command depending upon the image.
I believe that if your minSize values relative to -gravity go beyond the limits of the flat color region, then it will limit to the the image bounds or how much it will be reduced by the -fuzz.
It works for me for trimSize of 270x270 which is still larger than the image size of 256x256. So your comment about not working below 300x300 is not accurate.
magick lena_b50.png -define trim:minSize=270x270 -gravity center -trim lena_b50_trim2.png
Greatly based on fmw42's code snippet here, I have written a script to achieve the -minSize feature, tweaked to my taste.
If gravity=center, the cropped area is based on the centre of the original image, rather than adding even margins from the -trim detected area. This is because, in case the detected area is biased to one side, the produced result will be less biased to one side, which is more reasonably centred.
For other gravity settings, it acts like the gravitational force is applied from that side. For example, for gravity=southwest, the result image is "attracted" to the lower left corner (SW). This is an opposite interpretation of fmw42's code snippet in that link.
Last but not least, it works even if -minSize exceeds the original image size, and also works for -minSize smaller than the -trim detected size.
Here is my script:
#!/bin/sh
# Usage: ebook.trim.minSize input.jpg 75% east,south,west 1024 768 north output.jpg
input=$1; fuzz=$2; trimEdges=$3; minw=$4 ; minh=$5; output=$7
gravity=$( printf '%s' "$6" | tr '[:upper:]' '[:lower:]' | sed 's/^centre$/center/' )
w=$(magick "$input" -format '%w' info:)
h=$(magick "$input" -format '%h' info:)
trimvals=$(magick "$input" -fuzz "$fuzz" -define trim:edges="$trimEdges" -format '%#' info: | tr 'x' '+')
ww=$(printf '%s' "$trimvals" | cut -d+ -f1)
hh=$(printf '%s' "$trimvals" | cut -d+ -f2)
x0=$(printf '%s' "$trimvals" | cut -d+ -f3)
y0=$(printf '%s' "$trimvals" | cut -d+ -f4)
x1=$((w-x0-ww))
y1=$((h-y0-hh))
# Ensure $minw <= $w
if [ "$minw" -gt "$w" ]; then minw=$w; fi
# Ensure $minh <= $h
if [ "$minh" -gt "$h" ]; then minh=$h; fi
# validate user input $gravity
case $gravity in
center) ;;
north) ;;
northeast) ;;
east) ;;
southeast) ;;
south) ;;
southwest) ;;
west) ;;
northwest) ;;
*) printf "error \$gravity=%s\n" "$gravity"; exit;
esac
fixMinSize() {
trimSize=$1 ; minSize=$2 ; imgSize=$3
nearMargin=$4 ; farMargin=$5
nearEnd=$6 ; farEnd=$7 ; adjNear=$8 ; adjFar=$9
# Ensure this validity:
# detected trim size <= defined min size <= image side dimension
# $trimSize <= $minSize <= $imgSize
# if $trimSize >= $minSize then nothing needed to be done.
# if $trimSize < $minSize then need to expand $trimSize.
if [ "$trimSize" -lt "$minSize" ]; then
# if $gravity = << center >> || << north or west >> || << south or east >>
if [ "$gravity" = 'center' ] || [ "$gravity" = "$adjNear" ] || [ "$gravity" = "$adjFar" ]; then
evenMargin=$(( (imgSize - minSize) / 2 ))
# if -trim detected zone is << LEFT / TOP >> of the center zone,
# i.e. it exceeds the center zone at the near end,
# then nothing needed to be done. Will do $trimSize=$minSize at the end.
# No worries, $trimSize <= $minSize <= $imgSize. It won't pop out.
if [ "$evenMargin" -gt "$nearMargin" ]; then
:
# if -trim detected zone is << RIGHT / BOTTOM >> of the center zone,
# i.e. it exceeds the center zone at the far end,
# then shift the trim zone as if gravity={ east or south }.
# This takes care of odd number margins
elif [ $(( imgSize - evenMargin - minSize )) -gt "$farMargin" ]; then
nearMargin=$(( imgSize - farMargin - minSize ))
# else -trim detected zone is << WITHIN >> the center zone
else
nearMargin=$evenMargin
fi
# if $gravity contains << west or north >> i.e. the near end.
elif [ "${gravity#*"$nearEnd"}" != "$gravity" ]; then
# if $(( nearMargin + minSize )) pops out of the image dimension in the far end
if [ $(( nearMargin + minSize )) -gt "$imgSize" ]; then
nearMargin=$(( imgSize - minSize ))
fi
# if $gravity contains << east or south >> i.e. the far end.
elif [ "${gravity#*"$farEnd"}" != "$gravity" ]; then
nearMargin=$(( imgSize - farMargin - minSize ))
# if $nearMargin pops out of the image in the near end
if [ $nearMargin -lt 0 ]; then
nearMargin=0
fi
fi
trimSize=$minSize
fi
}
# Handle latitudinal trim zone shift
fixMinSize "$ww" "$minw" "$w" "$x0" "$x1" 'west' 'east' 'north' 'south'
ww=$trimSize
x0=$nearMargin
# Handle longitudinal trim zone shift
fixMinSize "$hh" "$minh" "$h" "$y0" "$y1" 'north' 'south' 'west' 'east'
hh=$trimSize
y0=$nearMargin
# -trim zone is fixed according to minSize and gravity, actual -crop here.
magick "${input}" -crop "${ww}x${hh}+${x0}+${y0}" +repage "${output}"
To test the script, download fmw42's image. Rename it to lena_b50.png. Run the following test script:
#!/bin/sh
# One liner test
# ~/bin/ebook.trim.minSize lena_b50.png 123 356 northeast output.png
mkdir -pv fit ori out
mkdir -pv fitWidth_oriHeight fitWidth_else oriWidth
mkdir -pv fitHeight_oriWidth fitHeight_else oriHeight
for minWidth in 0 20 240 256 266 300 333 356 380; do
for minHeight in 0 20 240 256 266 300 333 356 380; do
for gravity in center north northeast east southeast south southwest west northwest; do
if [ ! "$minWidth" -gt 256 ] && [ ! "$minHeight" -gt 256 ]; then folder='fit'
elif [ ! "$minWidth" -gt 256 ] && [ ! "$minHeight" -lt 356 ]; then folder='fitWidth_oriHeight'
elif [ ! "$minHeight" -gt 256 ] && [ ! "$minWidth" -lt 356 ]; then folder='fitHeight_oriWidth'
elif [ ! "$minWidth" -gt 256 ]; then folder='fitWidth_else'
elif [ ! "$minHeight" -gt 256 ]; then folder='fitHeight_else'
elif [ ! "$minWidth" -lt 356 ] && [ ! "$minHeight" -lt 356 ]; then folder='ori'
elif [ ! "$minWidth" -lt 356 ]; then folder='oriWidth'
elif [ ! "$minHeight" -lt 356 ]; then folder='oriHeight'
else folder='out'
fi
output_image_name="output_${gravity}_${minWidth}x${minHeight}.png"
~/bin/ebook.trim.minSize lena_b50.png "$minWidth" "$minHeight" "$gravity" "${folder}/${output_image_name}"
output_image_width=$( magick "${folder}/$output_image_name" -format '%w' info:)
output_image_height=$(magick "${folder}/$output_image_name" -format '%h' info:)
expected_width=$minWidth; expected_height=$minHeight
if [ "$minWidth" -lt 256 ]; then expected_width=256; fi
if [ "$minHeight" -lt 256 ]; then expected_height=256; fi
if [ "$minWidth" -gt 356 ]; then expected_width=356; fi
if [ "$minHeight" -gt 356 ]; then expected_height=356; fi
if [ "$output_image_width" -ne $expected_width ] || [ "$output_image_height" -ne $expected_height ]; then
echo 'error!!'; exit
fi
done
done
done
Related
I need to create a collage of 12 JPEG images using ImageMagick montage command:
montage image{1..12}.jpg -tile 3x4 -geometry +10+10 output.jpg
The command above creates a collage of 4 rows and 3 columns.
My aim is to add 3 labels (a), (b), (c) to the columns.
The result should look like:
(a) (b) (c)
img1 img2 img3
img4 img5 img6
img7 img8 img9
img10 img11 img12
I have tried using the -label flag but I can't get it to work.
My question is how can I add the labels as shown above?
I have the following version of ImageMagick:
Version: ImageMagick 7.1.0-13 Q16-HDRI x86_64 2021-10-29 https://imagemagick.org
Copyright: (C) 1999-2021 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.5)
Delegates (built-in): bzlib fontconfig freetype jbig jng jp2 jpeg lcms lzma pangocairo png tiff webp x xml zip zlib
Compiler: gcc (8.4)
You can do that in Imagemagick by appending a label above the first 3 images and piping all images to montage. I use -smush to add space rather than -append.
convert \
\( -pointsize 32 label:"(a)" lena.jpg -gravity center -smush 20 -set label "" \) \
\( -pointsize 32 label:"(b)" mandril3.jpg -gravity center -smush 20 -set label "" \) \
\( -pointsize 32 label:"(c)" zelda1.jpg -gravity center -smush 20 -set label "" \) \
zelda1.jpg lena.jpg mandril3.jpg miff:- |\
montage - -tile 3x2 -geometry +10+10 result.jpg
Problem
In my quite short script I have the problem that it sometimes reports that the filename or extension is too long. Depending on the $image and $size values in my script this error may occur or not.
E.g. the script below produces this error with the image from here - saved and converted to "example3.png".
I do use Version: ImageMagick 7.0.10-62 Q16 x64 on windows and I don't know what to do with the error message... Any ideas what the problem is here?
Powershell script
#####################
# Setup
#####################
$image = "./example3.png"
$out = "./result.png"
$outPalette = "./palette.png"
$size = 50
$fuzz = 50
$colors = 6
$resizedSize = "$($size)x$($size)`!"
$histogramSize = "$($size)x$($size)"
#####################
# Program
#####################
Write-Host ""
# 1) Scale + change depth + remove unwanted colors (b/w)
Write-Host "- Step 1..." -ForegroundColor Green
magick convert $image -scale $resizedSize -depth 8 `
-fuzz $fuzz -transparent black -transparent white `
$out
#2) create histogram with the help of the sparse colors
Write-Host "- Step 2..." -ForegroundColor Green
$dataHistogram = magick convert -size $histogramSize xc: -sparse-color voronoi ( magick convert $out sparse-color: ) +dither -colors $colors -depth 8 -format %c histogram:info:
# ... more ...
Edit: Adjustments
replaced magick convert with magick
replaced $fuzz = 50 with $fuzz = "50%"
replaced $size = 50 with $size = 100
More images do work now but e.g. following still fails with the same error:
Edit2:
The result of the inner magick command (magick convert $out sparse-color:) looks like following:
# ImageMagick pixel enumeration: 100,100,255,srgba
0,0: (87,72,86,0) #57485600 srgba(87,72,86,0)
1,0: (105,81,91,0) #69515B00 srgba(105,81,91,0)
...
I am not sure what's going on with powershell but if the issue is the length of the command-line, you can supply the sparse colour from a file like this:
magick -size 800x600 xc: -sparse-color voronoi #colors.txt result.png
Or on stdin like this:
echo "10,10 red 200,200 yellow" | magick -size 800x600 xc: -sparse-color voronoi #- result.png
I am running ImageMagick on Mac OS High Sierra
The following commands work fine with ImageMagick 6.9.0
convert -define stream:buffer-size=0 png:- png:- -alpha off -compose copy-opacity -composite png:-
compare -define stream:buffer-size=0 -fuzz 17% -metric AE png:- png:- png:-
I updated ImageMagick 6.9.0 to ImageMagick 7.0.7-28 then both of these commands started failing with the below error messages
magick -define stream:buffer-size=0 png:- png:- -alpha off -compose copy-opacity -composite png:-
magick: improper image header `/var/folders/tb/11n2czg57ts9dzxypdsmlqk99c46m9/T/magick-26635byT1dtHsAuT3' # error/png.c/ReadPNGImage/4231.
magick compare -define stream:buffer-size=0 -fuzz 17% -metric AE png:- png:- png:-
For input string: "compare: improper image header `/var/folders/tb/11n2czg57ts9dzxypdsmlqk99c46m9/T/magick-26363xwcFdjrv3CT0' # error/png.c/ReadPNGImage/4231."
Can you please guide me what I have to change in those commands?
If I store png files in a temporary folder and run the above commands by replacing png:- with temporary file path then both the commands run fine. But I want the commands to work with InputStream.
Thanks in advance!
I'm not sure you can stream two PNG files concatenated together as PNGs into ImageMagick's input stream. Essentially, you are trying to do this:
{ convert xc:red png:- ; convert xc:blue png:- ; } | convert png:- png:- -append result.png
which doesn't work, because, I think, the final convert will read the entire input stream when it encounters the first png:- and there will be nothing left for the second png:-.
I think the only safe way to send multiple concatenated images through a single channel is by using the MIFF "Magic Image File Format" which does support multiple images:
{ convert xc:red miff:- ; convert xc:blue miff:- ; } | convert miff:- -append result.png
In the illustration below, the blue rectangles represent arbitrary source images. For each image, I want to extract a section (shown in red) which is
of a specified aspect ratio (in this example, they are all 3:2)
as large as possible while fitting within the source image
centred within the source image
How can I do this with ImageMagick command-line tools?
You can crop the largest possible 3:2 section from the center of an image with a command like this...
convert input.png \
-set option:distort:viewport "%[fx:(w/3)<(h/2)?w:h*3/2]x%[fx:(w/3)<(h/2)?w*2/3:h]" \
\( xc: -distort SRT 0 \) +swap -gravity center -composite output.png
That uses the input image's dimensions to calculate the size of the output image, creates a blank image of those dimensions as a sort of template, then composites the input image centered over that template. The result is essentially a 3:2 image cropped from the center of the input.
Edited to add...
Here is another method that simply resets the page information to specify new canvas dimensions and offsets, then flattens the image properly located within that new canvas.
convert input.png \
-set page "%[fx:(w/3)<(h/2)?w:h*3/2]x%[fx:(w/3)<(h/2)?w*2/3:h]" \
-set page "-%[fx:(w/3)<(h/2)?0:(w-(h*3/2))/2]-%[fx:(w/3)<(h/2)?(h-(w*2/3))/2:0]" \
-flatten output.png
This doesn't have to create a template image or do a composite operation, and in testing it seems to be far faster than my other suggestion above.
If you only want horizontal crops with w>h aspect, then you can do that in ImageMagick 6 as follows in Unix syntax:
Input:
infile="monet2.jpg"
aspect="3:2"
ww=`convert -ping "$infile" -format "%w" info:`
hh=`convert -ping "$infile" -format "%h" info:`
ratio=`convert xc: -format "%[fx:$ww/$hh]" info:`
aspect1=`echo $aspect | cut -d\: -f1`
aspect2=`echo $aspect | cut -d\: -f2`
aspect=`convert xc: -format "%[fx:$aspect1/$aspect2]" info:`
test=`convert xc: -format "%[fx:$aspect>=$ratio?1:0]" info:`
if [ $test -eq 1 ]; then
width=$ww
height=`convert xc: -format "%[fx:$hh*$ratio/$aspect]" info:`
else
width=`convert xc: -format "%[fx:$ww*$aspect/$ratio]" info:`
height=$hh
fi
convert "$infile" -gravity center -crop ${width}x${height}+0+0 +repage result.jpg
Input:
infile="barn.jpg"
aspect="3:2"
ww=`convert -ping "$infile" -format "%w" info:`
hh=`convert -ping "$infile" -format "%h" info:`
ratio=`convert xc: -format "%[fx:$ww/$hh]" info:`
aspect1=`echo $aspect | cut -d\: -f1`
aspect2=`echo $aspect | cut -d\: -f2`
aspect=`convert xc: -format "%[fx:$aspect1/$aspect2]" info:`
test=`convert xc: -format "%[fx:$aspect>=$ratio?1:0]" info:`
if [ $test -eq 1 ]; then
width=$ww
height=`convert xc: -format "%[fx:$hh*$ratio/$aspect]" info:`
else
width=`convert xc: -format "%[fx:$ww*$aspect/$ratio]" info:`
height=$hh
fi
convert "$infile" -gravity center -crop ${width}x${height}+0+0 +repage result2.jpg
If on a Unix-like OS, then see my script, aspectcrop, at http://www.fmwconcepts.com/imagemagick/index.html
If you provide w<h aspect, then the same code will crop vertically.
In ImageMagick 7, you can do it in one command line, if you provide the aspect as a fraction rather than a colon separated ratio:
infile="monet2.jpg"
aspect="1.5"
magick "$infile" \
-gravity center \
-crop "%[fx:$aspect>=(w/h)?w:w*$aspect/(w/h)]x%[fx:$aspect>=(w/h)?h*(w/h)/$aspect:h]+0+0" \
+repage \
result.jpg
I use Imagemagick (www.imagemagick.org)
Since i am on hostgator i also have imagick and magickwand installed.
I can do simple manipulation with imagick and magickwand but if i want to reproduce the advanced tutorials at imagemagick.org i fail.
Goal:
make this working http://www.imagemagick.org/Usage/advanced/#jigsaw
Questions:
How can i do this with imagick or magickwand?
Could i somehow also communicate with the module imagemagick through command line, like exec(....)?
Thanks 4 short help
You can use exec() or shell_exec().
For example:
exec('/path/to/your/imagick/convert jigsaw_tmpl.png -edge .5 -blur 0x.5 jigsaw_edge.png');
One more reminder, exec() will not work in PHP safe mode.
Okay. The solution using the command-line commands straight is like the following:
exec("/usr/lib/convert user/set/seinfeld/image/image/data/apple_cinema_30.jpg -edge .5 -blur 0x.5 jaw_ege.png");
so obviously you have to know the path to the module and set the path to the images correctly (a).
will update if necessary with the instructions for imagick/magickwand.
I think it is to complicated to be run in Imagick - not saying it could not be - and as said above the best bet would be Imagemagick command line and exec( ). Build it up one command at a time; you may be able to combine commands later. Do not use jpg for any intermediate images as you will start to loose quality.
It depends what effect you are after as Anthony has a Bash script you could use linked towards the bottom of that section of the page.
You can run that with php using exec:
Upload the script to your server
CHMOD it to either 755 or 777 depending on your server setup
// Run the script
exec("/FULL PATH TO JIGSAW/jigsaw options input.jpg mask.png output.png 2>&1", $array);
//Display any errors
echo "<br>".print_r($array)."<br></pre>";
I do not know if this will work on a Hostgator account but I can not see why not.
Also I have not tried it and you need a mask image to go with your input image.
I have just tried this on my server and get an error: /bin/bash^M: bad interpreter: No such file or directory
This means nothing to me!
Making one jigsaw piece using Anthony's images and code with Imagemagick commaand line and exec( )
exec("convert jigsaw_tmpl.png -edge .5 -blur 0x.5 jigsaw_edge.png");
$cmd = " holocaust_md.jpg \( jigsaw_edge.png -negate \) -geometry +365+96 ".
" -compose multiply -composite -crop 100x100+365+96 +repage ";
exec("convert $cmd jigsaw_outline.png");
$cmd = " holocaust_md.jpg -crop 100x100+365+96! -background none -flatten ".
" +repage \( jigsaw_tmpl.png +matte \) -compose CopyOpacity -composite ".
" -rotate -20 -gravity center -crop 100x100+0+0 +repage ";
exec("convert $cmd jigsaw_cutout.png");
$cmd = " jigsaw_cutout.png \( +clone -channel A -separate +channel -negate ".
" -background black -virtual-pixel background -blur 0x2 -shade 120x21.78 ".
" -contrast-stretch 0% +sigmoidal-contrast 7x50% -fill grey50 -colorize 10% ".
" +clone +swap -compose overlay -composite \) -compose In -composite ";
exec("convert $cmd jigsaw_bevel.png");
$cmd = " jigsaw_bevel.png \( +clone -fill DarkSlateGrey -colorize 100% -repage +0+1 \) ".
" \( +clone -repage +1+2 \) \( +clone -repage +1+3 \) \( +clone -repage +2+4 \) ".
" \( +clone -repage +2+5 \) -background none -compose DstOver -flatten";
exec("convert $cmd jigsaw_thickness.png");
$cmd = " jigsaw_thickness.png \( +clone -background Black -shadow 50x3+4+4 \) ".
" -background none -compose DstOver -flatten";
exec("convert $cmd jigsaw_shadow.png");