Random Image Auto Rescale - php

I am currently using http://photomatt.net/scripts/randomimage to display a random background image. I would like to have these images automatically rescale (dynamically?) according to the window or div width. Is this even possible? Code would be incredible if you have the time and ability. :)
Thanks in advance!
Here is the current random image code for your convenience:
<?php
// Make this the relative path to the images, like "../img" or "random/images/".
// If the images are in the same directory, leave it blank.
$folder = '';
// Space seperated list of extensions, you probably won't have to change this.
$exts = 'jpg jpeg png gif';
$files = array(); $i = -1; // Initialize some variables
if ('' == $folder) $folder = './';
$handle = opendir($folder);
$exts = explode(' ', $exts);
while (false !== ($file = readdir($handle))) {
foreach($exts as $ext) { // for each extension check the extension
if (preg_match('/\.'.$ext.'$/i', $file, $test)) { // faster than ereg, case insensitive
$files[] = $file; // it's good
++$i;
}
}
}
closedir($handle); // We're not using it anymore
mt_srand((double) microtime()*1000000); // seed for PHP < 4.2
$rand = mt_rand(0, $i); // $i was incremented as we went along
header('Location: '.$folder.$files[$rand]); // Voila!

Well, I would probably take the javascript approach.
Load the image up behind the scenes in a hidden image element.
Bind to the image element's onload event so you know when it's completed.
Get the width/height of the image after it's loaded and use that to apply CSS/etc. to the page based on what the browser looks like, the image size is, etc.
Pseudo-Code:
var body = document.getElementsByTagName('body')[0];
var img = document.createElement('img');
img.src = 'random_image.php';
img.style.display = 'none';
img.onload = function(){
// modify the background styles based on your own conditions
};
body.appendChild(img);
If you really wanted to get fancy, you could bind to the window re-size event and continue to change the random image based on what the visible screen size, browser window size, etc. are.

Related

PHP trying to understand how to generate thumbnail from directory

This is currently what I have. When I include it in my index.php and then call the function on pageload, I get a blank page. So something is wrong here, but I don't know what. I feel like I'm really close though. I just want to create thumbnails of images in a directory, and then show them in HTML as a list of images you can click that trigger lightboxes.
I'm still really shaky in PHP. I'm trying to wrap my head around editing images in a directory.
<?php
function buildThumbGallery(){
$h = opendir('/Recent_Additions/'); //Open the current directory
while (false !== ($curDir = readdir($h))) {
if (!file_exists('/Recent_Additions/thumbs/')) {
$thumbDir = mkdir('/Recent_Additions/thumbs/', 0777, true);
}else{
$thumbDir = '/Recent_Additions/thumbs/';
}
$width = 200;
$height = 200;
foreach ($curDir as $image) {
$filePath = $curDir."/".$image;
$genThumbImg = $image->scaleImage($width, $height, true);
$newThumb = imagejpeg($genThumbImg, $thumbDir, 100);
echo '<li> <a class="fancybox" data-fancybox-group="'.basename($curDir).'" href="'.$filePath.'" title="'.basename($curDir)." ".strpbrk(basename($filePath, ".jpg"), '-').'"><img src="'.$newThumb.'"/>'.basename($curDir).'</a>';
imagedestroy($newThumb);
}echo '</li>';
}
?>
You are doing several things wrong:
You're not closing the while loop.
Readdir already loops through a directory, your foreach is not doing anything.
You are missing quotes in your echo.
You are calling the method scaleImage on a string, I think you meant to call the function imagescale.
You're missing and misunderstanding a lot of stuff, take a look at how to create a thumbnail here: https://stackoverflow.com/a/11376379/4193448
Also see if you can enable PHP errors, getting a blank page while your code is full of errors is not really helping is it?
::EDIT::
With help from #swordbeta, I got my script working properly. Here is the code for future reference:
<?php
function buildThumbGallery(){
$curDir = "./Recent_Additions/";
$thumbsPath = $curDir."thumbs/";
if (!file_exists($thumbsPath)) {
mkdir($thumbsPath, 0777, true);
}
foreach(scandir($curDir) as $image){
if ($image === '.' || $image === '..' || $image === 'thumbs') continue;
if(!file_exists($thumbsPath.basename($image, ".jpg")."_thumb.jpg")){
// Max vert or horiz resolution
$maxsize=200;
// create new Imagick object
$thumb = new Imagick($curDir.$image); //'input_image_filename_and_location'
$thumb->setImageFormat('jpg');
// Resizes to whichever is larger, width or height
if($thumb->getImageHeight() <= $thumb->getImageWidth()){
// Resize image using the lanczos resampling algorithm based on width
$thumb->resizeImage($maxsize,0,Imagick::FILTER_LANCZOS,1);
}else{
// Resize image using the lanczos resampling algorithm based on height
$thumb->resizeImage(0,$maxsize,Imagick::FILTER_LANCZOS,1);
}
// Set to use jpeg compression
$thumb->setImageCompression(Imagick::COMPRESSION_JPEG);
$thumb->setImageCompressionQuality(100);
// Strip out unneeded meta data
$thumb->stripImage();
// Writes resultant image to output directory
$thumb->writeImage($thumbsPath.basename($image, ".jpg")."_thumb.jpg"); //'output_image_filename_and_location'
// Destroys Imagick object, freeing allocated resources in the process
$thumb->destroy();
}else{
echo '<a class="fancybox" data-fancybox-group="'.basename($curDir).'" href="'.$curDir.basename($image, "_thumb.jpg").'" title="Recent Addition - '.basename($image, ".jpg").'"><img src="'.$thumbsPath.basename($image, ".jpg")."_thumb.jpg".'"/></a>';
echo '<figcaption>'.basename($image, ".jpg").'</figcaption>' . "<br/>";
}
}
}
?>
::Original Post::
Ok, after going back and doing some more research and suggestions from #swordbeta, i've got something that works. My only issue now is I can't get the images to show in my index.php. I'll style the output in CSS later, right now I just want to see the thumbnails, and then later build them into lightbox href links:
<?php
function buildThumbGallery(){
$curDir = "./Recent_Additions/";
$thumbsPath = $curDir."/thumbs/";
if (!file_exists($thumbsPath)) {
mkdir($thumbsPath, 0777, true);
}
$width = 200;
foreach(scandir($curDir) as $image){
if ($image === '.' || $image === '..') continue;
if(file_exists($thumbsPath.basename($image)."_thumb.jpg")){
continue;
}else{
// Max vert or horiz resolution
$maxsize=200;
// create new Imagick object
$thumb = new Imagick($curDir.$image); //'input_image_filename_and_location'
// Resizes to whichever is larger, width or height
if($thumb->getImageHeight() <= $thumb->getImageWidth()){
// Resize image using the lanczos resampling algorithm based on width
$thumb->resizeImage($maxsize,0,Imagick::FILTER_LANCZOS,1);
}else{
// Resize image using the lanczos resampling algorithm based on height
$thumb->resizeImage(0,$maxsize,Imagick::FILTER_LANCZOS,1);
}
// Set to use jpeg compression
$thumb->setImageCompression(Imagick::COMPRESSION_JPEG);
$thumb->setImageCompressionQuality(100);
// Strip out unneeded meta data
$thumb->stripImage();
// Writes resultant image to output directory
$thumb->writeImage($thumbsPath.basename($image)."_thumb.jpg"); //'output_image_filename_and_location'
// Destroys Imagick object, freeing allocated resources in the process
$thumb->destroy();
}
} echo '<img src="'.$thumbsPath.basename($image)."_thumb.jpg".'" />' . "<br/>";
}
?>
At the moment, the output from the echo isn't showing anything, but the rest of the script is working properly (i.e. generating thumbnail images in a thumbs directory).
I'm guessing i'm not formatting my echo properly. This script is called in my index.php as <?php buildThumbGallery(); ?> inside a styled <div> tag.

PHP show thumbnail depending on file type

All the files in a certain directory are scanned using scandir() for example. How then do I go through the files in that directory and create a small image (thumbnail) or whatever so that I can display that next to the name.
I will probably check the files one by one, and lets say it is another directory, the image will be default folder image. For PDF's maybe also. But then for video's and images and anything else like it, the image should be like a preview.
<?php
$data = array();
$files = array();
$allFiles = scandir($_REQUEST['dir_name']);
$files = array_diff($allFiles, array('.', '..'));
foreach($files as $key=>$file){
$data[$key]['name'] = $file;
if(is_dir(_REQUEST['dir_name'].'/'.$file)){
//Get small image of folder here and store that in $data[$key]['preview']
$data[$key]['type'] = 'dir';
}
else{
$extension = substr(strrchr($filename, "."));
$data[$key]['type'] = $extension;
switch ()$extension) {
case 'jpeg' : {
//Get small thumbnail of jpeg image here and store that in $data[$key]['preview'];
}
case 'png' : {
//Get small thumbnail of png image here and store that in $data[$key]['preview'];
}
case 'pdf' : {
//Get small thumbnail of pdf here and store that in $data[$key]['preview'];
}
case 'rar' : {
//Get small thumbnail of default .rar image here and store that in $data[$key]['preview'];
}
}
}
}
echo json_encode($data);
?>
I am prepared to do quite a few extensions, and maybe find a default later on for extensions not explicitly covered. I just need to know some of the different methods on generating a thumbnail from images, videos and documents as I suspect they are completely different.

Saving Each PDF Page to an Image Using Imagick

I have the following php function below that's converting a local PDF file into images. In short, I want each PDF page to be converted to a separate image.
The function converts the PDF to an image - but only the last page. I want every page of the PDF to be converted to a image and numbered. Not just the last page of the PDF.
Currently, this function converts the last page of example.pdf to example-0.jpg. Issue I'm sure lies within the for method. What am I missing?
$file_name = 'example.pdf'; // using just for this example, I pull $file_name from another function
function _create_preview_images($file_name) {
// Strip document extension
$file_name = basename($file_name, '.pdf');
// Convert this document
// Each page to single image
$img = new imagick('uploads/'.$file_name.'.pdf');
// Set background color and flatten
// Prevents black background on objects with transparency
$img->setImageBackgroundColor('white');
$img = $img->flattenImages();
// Set image resolution
// Determine num of pages
$img->setResolution(300,300);
$num_pages = $img->getNumberImages();
// Compress Image Quality
$img->setImageCompressionQuality(100);
// Convert PDF pages to images
for($i = 0;$i < $num_pages; $i++) {
// Set iterator postion
$img->setIteratorIndex($i);
// Set image format
$img->setImageFormat('jpeg');
// Write Images to temp 'upload' folder
$img->writeImage('uploads/'.$file_name.'-'.$i.'.jpg');
}
$img->destroy();
}
Seems like most of my code was correct. The issue was, I was using $img->flattenImages(); incorrectly. This merges a sequence of images into one image. Much like how Photoshop flattens all visible layers into an image when exporting a jpg.
I removed the above line and the individual files were written as expected.
/* convert pdf file to list image files */
if($_FILES['file_any']['type']=='application/pdf'){
$file_name = str_replace(substr($url,0,strpos($url,$_FILES['file_any']['name'])),'',$url);
$basename = substr($file_name,0,strpos($file_name,'.'));
$abcd = wp_upload_dir();
$delpath = $abcd['path'];
$savepath = $abcd['url'];
$dirpath = substr($savepath,(strpos($savepath,'/upl')+1));
$file_name = basename($file_name, '.pdf');
$img = new imagick($delpath.'/'.$file_name.'.pdf');
$img->setImageBackgroundColor('white');
$img->setResolution(300,300);
$num_pages = $img->getNumberImages();
$img->setImageCompressionQuality(100);
$imageurl = NULL;
$imagedelurl = NULL;
for($i = 0;$i < $num_pages; $i++) {
$imageurl[]=$savepath.'/'.$basename.'-'.$i.'.jpg';
$imagedelurl[] = $delpath.'/'.$basename.'-'.$i.'.jpg';
// Set iterator postion
$img->setIteratorIndex($i);
// Set image format
$img->setImageFormat('jpeg');
// Write Images to temp 'upload' folder
$img->writeImage($delpath.'/'.$file_name.'-'.$i.'.jpg');
}
$img->destroy();
}
There is a much easier way without the loop, just use $img->writeImages($filename,false); and it will make a file per PDF-page. As you said, if you flatten the image first, it only saves 1 page.
first install
imagemagick
in your system or server
and then create
pdfimage
folder and put pdf file in this folder then run the code and upload it file
<?php
$file_name = $_FILES['pdfupload']['name']; // using just for this example, I pull $file_name from another function
//echo strpos($file_name,'.pdf');
$basename = substr($file_name,0,strpos($file_name,'.'));
//echo $_FILES['pdfupload']['type'];
//if (isset($_POST['submit'])){
if($_FILES['pdfupload']['type']=='application/pdf'){
// Strip document extension
$file_name = basename($file_name, '.pdf');
// Convert this document
// Each page to single image
$img = new imagick('pdfimage/'.$file_name.'.pdf');
// Set background color and flatten
// Prevents black background on objects with transparency
$img->setImageBackgroundColor('white');
//$img = $img->flattenImages();
// Set image resolution
// Determine num of pages
$img->setResolution(300,300);
$num_pages = $img->getNumberImages();
// Compress Image Quality
$img->setImageCompressionQuality(100);
$images = NULL;
// Convert PDF pages to images
for($i = 0;$i < $num_pages; $i++) {
$images[]=$basename.'-'.$i.'.jpg';
// Set iterator postion
$img->setIteratorIndex($i);
// Set image format
$img->setImageFormat('jpeg');
// Write Images to temp 'upload' folder
$img->writeImage('pdfimage/'.$file_name.'-'.$i.'.jpg');
}
echo "<pre>";
print_r($images);
$img->destroy();
}
//}
?>

PHP - Get information about image (Height and Width) without loading it

Is it possible to get image information without loading the actual image with PHP? In my case I want the Height and Width.
I have this code to fetch images from a directory. I echo out the image's url and fetch it with JS.
<?php
$directory = "./images/photos/";
$sub_dirs = glob($directory . "*");
$i = 0;
$len = count($sub_dirs);
foreach($sub_dirs as $sub_dir)
{
$images = glob($sub_dir . '/*.jpg');
$j = 0;
$len_b = count($images);
foreach ($images as $image)
{
if ($j == $len_b - 1) {
echo $image;
} else {
echo $image . "|";
}
$j++;
}
if ($i == $len - 1) {
} else {
echo "|";
}
$i++;
}
?>
getImageSize() is the proper way to get this information in PHP
It does a minimal amount of work based on the type of image. For example, a GIF image's height/width are stored in a header. Very easy to access and read. So this is how the function most likely gets that information from the file. For a JPEG, it has to do a little more work, using the SOFn markers.
The fastest way to access this information would be to maintain a database of file dimensions every time a new one is uploaded.
Given your current situation. I recommend writing a PHP script that takes all of your current image files, gets the size with this function, and then inserts the info into a database for future use.
It depends what you mean by "without loading it".
The built-in getimagesize() does this.
list($w, $h) = getimagesize($filename);
You can programmatically get the image and check the dimensions using Javascript...
var img = new Image();
img.onload = function() {
alert(this.width + 'x' + this.height);
}
img.src = 'http://www.google.com/intl/en_ALL/images/logo.gif';
This can be useful if the image is not a part of the markup ;)
You can store the width'n'height information in a text file, and load it later on.
list($width, $height, $type, $attr) = getimagesize($_FILES["Artwork"]['tmp_name']);
Use this.

Filename image as Automatic caption

I am using this script to display random images from a folder. I have hundreds of images with significant filenames, So I’m looking for a way to display each image file name as an image caption. Is this possible?
this is the script Im using:
<?php
/*
By Matt Mullenweg > http://photomatt.net
Inspired by Dan Benjamin > http://hiveware.com/imagerotator.php
Latest version always at:
http://photomatt.net/scripts/randomimage
*/// Make this the relative path to the images, like "../img" or "random/images/".
// If the images are in the same directory, leave it blank.
$folder = '';
// Space seperated list of extensions, you probably won't have to change this.
$exts = 'jpg jpeg png gif';
$files = array(); $i = -1; // Initialize some variables
if ('' == $folder) $folder = './';
$handle = opendir($folder);
$exts = explode(' ', $exts);
while (false !== ($file = readdir($handle))) {
foreach($exts as $ext) { // for each extension check the extension
if (preg_match('/\.'.$ext.'$/i', $file, $test)) { // faster than ereg, case insensitive
$files[] = $file; // it's good
++$i;
}
}
}
closedir($handle); // We're not using it anymore
mt_srand((double)microtime()*1000000); // seed for PHP < 4.2
$rand = mt_rand(0, $i); // $i was incremented as we went along
header('Location: '.$folder.$files[$rand]); // Voila!
?>
If all you want to do is continue to display a single random image then remove (or comment out so you can restore it if you later want to) the header line and at the end of the file add the following lines underneath it:
//header('Location: '.$folder.$files[$rand]); // Voila!
echo $files[$rand];
?>
<br />
<img src="<?php echo $folder.$files[$rand] ?>" />
You might want to add some css styling to set the display size of the image, and to format the caption above it.

Categories