Skip to content

Instantly share code, notes, and snippets.

@Dan-Q
Created February 10, 2025 17:07
Show Gist options
  • Save Dan-Q/017dcc1147c9990f57cf16640215dd8d to your computer and use it in GitHub Desktop.
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/
<?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