Created
February 10, 2025 17:07
-
-
Save Dan-Q/017dcc1147c9990f57cf16640215dd8d to your computer and use it in GitHub Desktop.
Script to run via WP-CLI to generate "continuum" images (and associated HTML imagemaps) of the featured images associated with the posts in a WordPress blog. More details: https://danq.me/2025/02/10/continuum/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
# Run using WP-CLI, e.g. with `wp eval-file /path/to/generate-continuum.php` | |
$V_WIDTH = 640; | |
$H_HEIGHT = 1160; | |
$OUTPUT_DIR = '/home/dan/tmp'; | |
$OUTPUT_TMP_DIR = "$OUTPUT_DIR/thumbnails-banner-parts"; | |
$parts = []; | |
$posts_with_thumbnails = new WP_Query( | |
[ | |
'post_type' => 'post', | |
'meta_key' => '_thumbnail_id', | |
'post_status' => 'publish', | |
'order' => 'ASC', | |
'posts_per_page' => -1 | |
] | |
); | |
foreach( $posts_with_thumbnails->posts as $post ){ | |
$parts[] = [ | |
'post_id' => $post->ID, | |
'post_title' => $post->post_title, | |
'permalink' => get_permalink( $post ), | |
'thumbnail' => get_attached_file ( get_post_thumbnail_id( $post->ID ), 'original' ) | |
]; | |
} | |
// Build the banner slice images, deleting any "bad" (failed to convert) ones: | |
shell_exec("rm $OUTPUT_TMP_DIR/*.png"); | |
echo "Converting: "; | |
foreach( $parts as $i => $part ){ | |
// Horizontal mode: | |
$outfile = "$OUTPUT_TMP_DIR/h" . sprintf('%06d', $i) . '.png'; | |
$cmd = 'convert ' . $part['thumbnail'] . "[0] -resize 1x{$H_HEIGHT}\! " . $outfile . " || rm $outfile"; | |
shell_exec( $cmd ); | |
// Vertical mode: | |
$outfile = "$OUTPUT_TMP_DIR/v" . sprintf('%06d', $i) . '.png'; | |
$cmd = 'convert ' . $part['thumbnail'] . "[0] -resize {$V_WIDTH}x1\! " . $outfile . " || rm $outfile"; | |
shell_exec( $cmd ); | |
echo '.'; | |
} | |
echo "\n"; | |
// Horizontal - for all the successfully-converted images only, build an imagemap segment: | |
$valid_keys = array_map( fn($f)=>intval( preg_replace('/^.*?\/h(\d+).png$/', '\1', $f) ), glob("$OUTPUT_TMP_DIR/h*.png") ); | |
$map_areas = array_map( function($i, $x) use ($parts, $H_HEIGHT){ | |
$post_title = esc_attr( $parts[$i]['post_title'] ); | |
$post_href = esc_attr( $parts[$i]['permalink'] ); | |
return "<area shape=\"rect\" coords=\"$x,1,$x,{$H_HEIGHT}\" title=\"$post_title\" href=\"$post_href\">"; | |
}, $valid_keys, array_keys( $valid_keys ) ); | |
file_put_contents( "$OUTPUT_DIR/h.html", "<img src=\"h.png\" width=\"" . count( $map_areas ) . "\" height=\"{$H_HEIGHT}\" usemap=\"#tbpmap-h\">\n<map name=\"tbpmap-h\">\n" . implode( "\n", $map_areas ) . "\n</map>" ); | |
// Horizontal - combine all the slices: | |
shell_exec( "montage $OUTPUT_TMP_DIR/h*.png -tile x1 -geometry +0+0 -background white $OUTPUT_DIR/h.png" ); | |
// Vertical - for all the successfully-converted images only, build an imagemap segment: | |
$valid_keys = array_map( fn($f)=>intval( preg_replace('/^.*?\/v(\d+).png$/', '\1', $f) ), glob("$OUTPUT_TMP_DIR/v*.png") ); | |
$map_areas = array_map( function($i, $x) use ($parts, $V_WIDTH){ | |
$post_title = esc_attr( $parts[$i]['post_title'] ); | |
$post_href = esc_attr( $parts[$i]['permalink'] ); | |
return "<area shape=\"rect\" coords=\"1,$x,{$V_WIDTH},$x\" title=\"$post_title\" href=\"$post_href\">"; | |
}, $valid_keys, array_keys( $valid_keys ) ); | |
file_put_contents( "$OUTPUT_DIR/v.html", "<img src=\"v.png\" width=\"{$V_WIDTH}\" height=\"" . count( $map_areas ) . "\" usemap=\"#tbpmap-v\">\n<map name=\"tbpmap-v\">\n" . implode( "\n", $map_areas ) . "\n</map>" ); | |
// Vertical - combine all the slices: | |
shell_exec( "montage $OUTPUT_TMP_DIR/v*.png -tile 1x -geometry +0+0 -background white $OUTPUT_DIR/v.png" ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment