Automatic Image and Thumbnail Display
When you need to provide large or many images to someone, what do you do?
One way is to send several emails, each with some of the images attached, until all are sent. Another is to upload the images at the website of a third-party service and send instructions on how to access them.
Or, you could upload the images at your own website and send a viewing URL to the person.
Tap here for a live demo. The demo uses the very same web page and software that comes with this article.
To implement, do this:
-
Create a subdirectory on your server and make a note of the subdirectory's URL.
-
Upload the images into the subdirectory.
NOTE: The largest file size for an image that the software will process is 10 megabytes.
-
Upload the
index.php
web page and thepublishimages.php
PHP script into the subdirectory.Here is the source code of an
index.php
web page you may use. The style and content may be changed, but the PHPinclude()
directive needs to remain on the page where the image thumbnails shall be inserted. You'll see theinclude()
directive three text lines from the bottom of the following source code.<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Images</title> <style type="text/css"> * { box-sizing:border-box; } html, body { font-size:100%; font-family:sans-serif; } code { font-size:125%; padding-left:2px; padding-right:1px; } </style> </head> <body><div style="max-width:6in; margin:.5in auto;"> <div><a href="https://www.willmaster.com/"><img src="https://www.willmaster.com/images/wmlogo_icon.gif"></a></div> <h1> Images <!--<a href="/AIimages/index.html">(home)</a>--> </h1> <p> If images appear sideways, <a href="<?php echo($_SERVER['PHP_SELF'] . (isset($_GET['rotate'])?'':'?rotate=1') ) ?>">tap here</a> to reorient them. </p> <p> Below the thumbnail is the original image file name. Tap a thumbnail to pop up the original image within the dimensions of the browser window. For a larger image or to prepare for saving an image, tap the "new tab" icon on the left of the image file name. </p> </div> <?php include('publishimages.php') ?> </body> </html>
Note that the
<?php include('publishimages.php') ?>
line needs to be somewhere on the index page. It is the spot where the thumbnail images will be inserted. Thepublishimages.php
is the file name of the PHP script. If the PHP script file name is changed, then<?php include('publishimages.php') ?>
needs to be changed accordingly.Both the index page and the
publishimages.php
PHP script need to be in the subdirectory with the images.Here is the source code for the
publishimages.php
PHP script. No customization is required.<?php /* Display Thumbnails for Images in Directory Version 1.0 May 18, 2024 Will Bontrager Software LLC https://www.willmaster.com/ */ $BackgroundForLightbox = 'rgba(0,0,0,.5)'; $Resize['max-width'] = 200; $Resize['max-height'] = 200; $Resize['namechars'] = '_resized'; $Resize['MaxFileSizeForResizing'] = 10485760; $EmbeddedImageSRC = 'data:image/jpeg;base64,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'; $ImageDisplayTemplate = <<<TEMPLATE <div id="D{{INCREMENT}}" style="display:inline-block; position:relative; margin:1em;"> <div style="position:relative; width:{{W}}px; height:{{H}}px; outline:0px solid gold;"><img onclick="WillMaster_MakeImageBox('{{FILENAME}}')" src="{{THUMBNAME}}" style="{{IMGSTYLE}}"></div> <div><a target="_blank" href="{{FILENAME}}"><img src="$EmbeddedImageSRC" style="height:1em;"></a> {{FILENAME}}</div> </div> TEMPLATE; function ResizeAllNonresizedImages() { global $Resize; $needsResizing = array(); $alreadyDone = array(); foreach(glob('*.jpeg') as $f) { if( filesize($f)>$Resize['MaxFileSizeForResizing'] ) { continue; } if( preg_match('/'.$Resize['namechars'].'\.jpeg$/',$f) ) { $alreadyDone[preg_replace('/'.$Resize['namechars'].'\.jpeg$/','.jpeg',$f)] = true; } else { $needsResizing[$f] = true; } } foreach(glob('*.jpg') as $f) { if( filesize($f)>$Resize['MaxFileSizeForResizing'] ) { continue; } if( preg_match('/'.$Resize['namechars'].'\.jpg$/',$f) ) { $alreadyDone[preg_replace('/'.$Resize['namechars'].'\.jpg$/','.jpg',$f)] = true; } else { $needsResizing[$f] = true; } } foreach(glob('*.png') as $f) { if( filesize($f)>$Resize['MaxFileSizeForResizing'] ) { continue; } if( preg_match('/'.$Resize['namechars'].'\.png$/',$f) ) { $alreadyDone[preg_replace('/'.$Resize['namechars'].'\.png$/','.png',$f)] = true; } else { $needsResizing[$f] = true; } } foreach(glob('*.gif') as $f) { if( filesize($f)>$Resize['MaxFileSizeForResizing'] ) { continue; } if( preg_match('/'.$Resize['namechars'].'\.gif$/',$f) ) { $alreadyDone[preg_replace('/'.$Resize['namechars'].'\.gif$/','.gif',$f)] = true; } else { $needsResizing[$f] = true; } } foreach(glob('*.JPEG') as $f) { if( filesize($f)>$Resize['MaxFileSizeForResizing'] ) { continue; } if( preg_match('/'.$Resize['namechars'].'\.JPEG$/',$f) ) { $alreadyDone[preg_replace('/'.$Resize['namechars'].'\.JPEG$/','.JPEG',$f)] = true; } else { $needsResizing[$f] = true; } } foreach(glob('*.JPG') as $f) { if( filesize($f)>$Resize['MaxFileSizeForResizing'] ) { continue; } if( preg_match('/'.$Resize['namechars'].'\.JPG$/',$f) ) { $alreadyDone[preg_replace('/'.$Resize['namechars'].'\.JPG$/','.JPG',$f)] = true; } else { $needsResizing[$f] = true; } } foreach(glob('*.PNG') as $f) { if( filesize($f)>$Resize['MaxFileSizeForResizing'] ) { continue; } if( preg_match('/'.$Resize['namechars'].'\.PNG$/',$f) ) { $alreadyDone[preg_replace('/'.$Resize['namechars'].'\.PNG$/','.PNG',$f)] = true; } else { $needsResizing[$f] = true; } } foreach(glob('*.GIF') as $f) { if( filesize($f)>$Resize['MaxFileSizeForResizing'] ) { continue; } if( preg_match('/'.$Resize['namechars'].'\.GIF$/',$f) ) { $alreadyDone[preg_replace('/'.$Resize['namechars'].'\.GIF$/','.GIF',$f)] = true; } else { $needsResizing[$f] = true; } } foreach( $alreadyDone as $kk => $b ) { if(isset($needsResizing[$kk])) { unset($needsResizing[$kk]); } } $Resize['files'] = array_keys($needsResizing); ResizeImagesWithinArray($Resize); } # function ResizeAllNonresizedImages() function ResizeImagesWithinArray($data) { global $Resize; $arr = array(); $arr['width'] = $data['max-width']; $arr['height'] = $data['max-height']; $count = count($data['files']); for( $i=0; $i<$count; $i++ ) //$data['files'] as $f ); { $filename=__DIR__.'/' . $data['files'][$i]; $ext = imprintGetFileNameExtension($filename); $fname = preg_replace('/\.[^\.]+$/','',$filename); $arr['filename'] = $filename; $arr['ext'] = $ext; $arr['fname'] = $fname; $arr['source'] = "$fname.$ext"; $arr['dest'] = "$fname{$Resize['namechars']}.$ext"; ResizeTheImage($arr); } } # function ResizeImagesWithinArray() function ResizeTheImage($arr) { global $Resize; $src = trim($arr['source']); $dest = $arr['dest']; $destWidth = $arr['width']; $destHeight = $arr['height']; $th = getimagesize($src); $srcWidth = $th[0]; $srcHeight = $th[1]; if($srcWidth<=$Resize['max-width'] and $srcHeight<=$Resize['max-height']) { copy($arr['source'],$arr['dest']); return; } $arr = array(); $ta = explode('/',$th['mime']); if( count($ta)>1 ) { $type = array_pop($ta); } else { $type = imprintGetFileNameExtension($src); } $type = strtolower($type); $th = array(); $ta = array(); $adjustment = min( ( $destWidth / $srcWidth ), ( $destHeight / $srcHeight ) ); $destWidth = number_format( $srcWidth * $adjustment ); $destHeight = number_format( $srcHeight * $adjustment ); if( $srcWidth <= $destWidth and $srcHeight <= $destHeight ) { return; } // Start new image. $newimg = imagecreatetruecolor($destWidth, $destHeight); switch($type) { case 'jpeg': case 'jpg' : $oldimg = imagecreatefromjpeg($src); break; case 'png' : $oldimg = imagecreatefrompng($src); break; case 'gif' : $oldimg = imagecreatefromgif($src); break; default : return "Error: Unsupported image type."; } // Handle any transparency in GIF or PNG. if($type == "gif" or $type == "png") { imagecolortransparent( $newimg, imagecolorallocatealpha($newimg, 0, 0, 0, 127) ); imagealphablending( $newimg, false ); imagesavealpha( $newimg, true ); } // Create image. imagecopyresampled($newimg, $oldimg, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight); $outtype = $type; switch($outtype) { case 'jpeg': case 'jpg' : imagejpeg( $newimg, $dest, 100 ); break; case 'png' : imagepng( $newimg, $dest, 9 ); break; case 'gif' : imagegif( $newimg, $dest ); break; } return true; } # function ResizeTheImage() function imprintGetFileNameExtension($p) { $ta = explode('.',$p); $ext = array_pop($ta); return $ext; } # function imprintGetFileNameExtension() ResizeAllNonresizedImages(); echo <<<PAGEPART <script type="text/javascript"> /* Function WillMaster_MakeImageBox obtained from "Simple Image Lightbox" article at https://www.willmaster.com/library/optimization/simple-image-lightbox.php */ var WillMaster_ImageBoxNode; function WillMaster_MakeImageBox(url) { /* Will Bontrager Software LLC */ /* Simple Image Lightbox */ /* Version 1.0 */ /* January 18, 2020 */ /* Customization section. */ // Variable BackgroundColor needs to be assigned // the complete color for the background behind // the image in the lightbox. The value may be // rgba() or hsla() with valid parameters. // Examples: rgba(0,0,0,.5) and hsla(0,0%,0%,.5) var BackgroundColor = "$BackgroundForLightbox"; /* End of customization section. */ var DivIDvalue = "WillMaster_ImageBoxID"; if( url == DivIDvalue ) { document.body.removeChild(WillMaster_ImageBoxNode); return; } WillMaster_ImageBoxNode = document.createElement("div"); WillMaster_ImageBoxNode.id = DivIDvalue; WillMaster_ImageBoxNode.style.width = "100vw"; WillMaster_ImageBoxNode.style.height = "100vh"; WillMaster_ImageBoxNode.style.backgroundColor = BackgroundColor; WillMaster_ImageBoxNode.style.position = "fixed"; WillMaster_ImageBoxNode.style.left = "0"; WillMaster_ImageBoxNode.style.top = "0"; WillMaster_ImageBoxNode.setAttribute("onclick",arguments.callee.name+"('"+DivIDvalue+"')"); WillMaster_ImageBoxNode.innerHTML='<img src="'+url+'" style=" border:none; outline:none; max-width:100%; max-height:100%; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);" alt="lightbox image">'; document.body.appendChild(WillMaster_ImageBoxNode); } </script> PAGEPART; $FileList = array(); foreach(glob('*'.$Resize['namechars'].'.jpeg') as $f) { $FileList[] = $f; } foreach(glob('*'.$Resize['namechars'].'.jpg') as $f) { $FileList[] = $f; } foreach(glob('*'.$Resize['namechars'].'.png') as $f) { $FileList[] = $f; } foreach(glob('*'.$Resize['namechars'].'.gif') as $f) { $FileList[] = $f; } foreach(glob('*'.$Resize['namechars'].'.JPEG') as $f) { $FileList[] = $f; } foreach(glob('*'.$Resize['namechars'].'.JPG') as $f) { $FileList[] = $f; } foreach(glob('*'.$Resize['namechars'].'.PNG') as $f) { $FileList[] = $f; } foreach(glob('*'.$Resize['namechars'].'.GIF') as $f) { $FileList[] = $f; } sort($FileList); $i = strlen("yyyymmdd\t"); $increment = 1; $inclist = array(); foreach( $FileList as $f ) { $large = str_replace($Resize['namechars'],'',$f); $size = getimagesize($f); $w = $size[0]; $h = $size[1]; $imgstyle = ''; if( isset($_GET['rotate']) ) { $t = $w; $w = $h; $h = $t; $imgstyle = "transform-origin:top left; transform:rotate(90deg); position:absolute; top:0; left:{$w}px;"; } $chunk = str_replace('{{THUMBNAME}}',$f,$ImageDisplayTemplate); $chunk = str_replace('{{FILENAME}}',$large,$chunk); $chunk = str_replace('{{IMGSTYLE}}',$imgstyle,$chunk); $chunk = str_replace('{{INCREMENT}}',$increment,$chunk); $chunk = str_replace('{{W}}',$w,$chunk); $chunk = str_replace('{{H}}',$h,$chunk); $inclist[] = $increment; $increment++; echo $chunk; } ?>
Save the source code of the PHP script as filename
publishimages.php
. If the script is saved as a different*.php
file name, theinclude()
directive in theindex.php
file needs to be changed accordingly. -
Send your person the subdirectory's URL. As an example, if your subdirectory is named
/mythumbs
and your domain isexample.com
, then the subdirectory's URL would behttps://example.com/mythumbs
The first time the index page is loaded into a browser, the software will create thumbnail images from the images it finds in the directory. (The largest file size for an image that the software will process is 10 megabytes.)
If you have many images, it could take a while for the thumbnails to be created. If the software times out, simply reload the page and the software will continue making thumbnails.
When all the thumbnails are created, the page will load and publish the thumbnail images.
Every time the software runs, it looks for images that need to have thumbnails made. But it won't re-make thumbnails that already exist.
After the software is installed, you can still add and delete images in the subdirectory at any time. When deleting certain images, also delete the thumbnail version.
The software could be used to present images related to, as examples, holidays, special personal events, or product images. The really nice part of this whole thing is that the software automatically creates thumbnails as needed.
(This content first appeared in Possibilities newsletter.)
Will Bontrager