I currently have this snippet which spits out a random image
$imgDir = 'images/';
$images = glob($imagesDir . '*.{jpg}', GLOB_BRACE);
$randimg = $images[array_rand($images)];
but I want the image to be a certain width (600px), rather then warping images by using CSS is there a way the image width can be checked using PHP incorporating the code snippet above?
Yes, you can go through each individual file and check its size with getimagesize.
That's of course a very expensive operation to do every time. Instead, do this once and make the size part of the filename (e.g. foobar_500.jpg) and glob for that, or use a database to organize your images to begin with where you can save such metadata and query for it.
This will make sure you only select a random images from the images that have width 600
$imgDir = 'images/';
$images = glob($imgDir . '*.{jpg}', GLOB_BRACE);
$arr_images_600 = array();
foreach ($images as $img)
{
list($width, $height, $type, $attr) = getimagesize($img);
if ($width == 600) { $arr_images_600[] = $img; }
}
$randimg = $images[array_rand($arr_images_600)];
Related
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.
I am working on an uploader and slowly getting it working, I am uploading 3 images at once, and setting arrays for each one as keys, with an increment of ++1. I am wanting to resize the image before it gets copied to the thumbnail folder.
I have this code.
Everything works with it.
As you see, I started on getting the file info, but after that I am totally stuck on what to do after to resize the image proportionally with a maximum width of xpx and height to match it without looking distorted.
Any help would be really appreciated. Thank You.
EDIT --- I started working on it myself and wondering if this is the right approach to what i am doing.
<?php
if (isset($_POST['addpart'])) {
$image = $_FILES['images']['tmp_name'];
$name = $_POST['username'];
$i = 0;
foreach ($image as $key) {
$fileData = pathinfo(basename($_FILES["images"]["name"][$i]));
$fileName[] = $name . '_' . uniqid() . '.' . $fileData['extension'];
move_uploaded_file($key, "image/" . end($fileName));
copy("image/" . end($fileName), "image_thumbnail/" . end($fileName));
// START -- THE RESIZER THAT IS BEING WORKED ON
$source = "image_thumb/" . end($fileName);
$dest = "image_thumb/" . end($fileName);
$quality = 100;
$scale = 1 / 2;
$imsize = getimagesize($source);
$x = $scale * $imsize[0];
$y = $scale * $imsize[1];
$im = imagecreatefromjpeg($source);
$newim = imagecreatetruecolor($x, $y);
imagecopyresampled($newim, $im, 0, 0, 0, 0, $x, $y, $imsize[0], $imsize[1]);
imagejpeg($newim, $dest, $quality);
// END -- THE RESIZER THAT IS BEING WORKED ON
$i++;
}
echo 'Uploaded<br>';
echo 'Main Image - ' . $fileName[0] . '<br>';
echo 'Extra Image 1 - ' . $fileName[1] . '<br>';
echo 'Extra Image 2 - ' . $fileName[2] . '<br>';
echo '<hr>';
}
?>
thanks
Use GD library.
Create input image object using imagecreatefromstring() for example: imagecreatefromstring(file_get_contents($_FILES['images']['tmp_name'][$i]))
It's the simplest way.
Another option is to detect file type and use functions like imagecreatefromjpeg (), imagecreatefrompng(), etc.
Create output empty image using imagecreate()
Use imagecopyresampled() or imagecopyresized() to resize image and copy+paste it from input image to output image
Save output image using function like imagejpeg()
Clean memory using imagedestroy()
The built-in image manipulation commands of PHP makes your code difficult to understand and to maintain. I suggest you to use a library which wraps it into a more productive way.
If you use Intervention/image, for example, your code will look like this:
<?php
// target file to manipulate
$filename = $_FILES['images']['tmp_name'];
// create image instance
$img = Image::make($filename);
// resize to width, height
$img->resize(320, 240);
// save it!
$img->save('thumbs/'. uniqid() . '.' . pathinfo($filename, PATHINFO_EXTENSION));
Read the full documentation here: http://image.intervention.io/use/uploads
I am parsing website (not any in particular but a variety) and saving various information from them including images. So far I am saving the image src and then going back through again to check the size of the image. What I would like to do is check the image size when I first parse the page....
Here's what I have...
$imgs = $dom->getElementsByTagName('img');
$imageArray = array();
foreach ($imgs as $img) {
$image = $this->returnProperURL($img->getAttribute('src'));
$imageSize = getimagesize($image);
$imageWidth = $imageSize[0];
$imageHeight = $imageSize[1];
if($imageWidth > $this->minImageWidth && $imageHeight > $this->minImageHeight){
$imageArray[] = $image;
}
}
instead of using the getimagesize() after I have the image src is there a way I can check the image size the first time through when I am parsing it? As I'm sure you suspect, it's taking twice as long as it should.
I have a client that sends me text messages from his iPhone with images for me to upload into his gallery. I'm trying to create a admin system so I can simply take the images from the texts, go to the admin page on my iPhone and upload the images straight to the gallery.
This would save me tons of time in my day to day work schedule.
Using the provided code. How can I add the following functions:
I would like to compress the file size down to a smaller size if possible, similar to the save to web jpg function in Photoshop. (Most images I get are around 1-3 MB. I would like to get them down to around 150-500kb max)
I would like to automatically change the width to 760px, but keep the aspect ratio so the images are not squished. He sends me landscape and portrait images.
Beings they are iPhone images. They have an extension .JPG (all caps) I would like this to change to .jpg (all lower case.) This is not a deal breaker I would just like to know how to do this for future use.
Either one of these functions would be very helpful, but all 3 would be ideal for my situation.
Here is the code I'm working with?
THIS IS THE FINAL CORRECT CODE FOR UPLOADING AND RESIZING IMAGES PROVIDED By #tman
Make sure you have imagick installed in your php.ini file. Check with your hosting provider to install it.
<?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");
for($i=0;$i<count($_FILES["image"]["name"]);$i++){
if($_FILES["image"]["name"][$i] != ''){ // don't insert if file name empty
$dataType = mysql_real_escape_string($_POST["dataType"][$i]);
$title = mysql_real_escape_string($_POST["title"][$i]);
$fileData = pathinfo($_FILES["image"]["name"][$i]);
$fileName = uniqid() . '.' . $fileData['extension'];
$target_path = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName;
if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path)){ // The file is in the images/gallery folder.
// Insert record into database by executing the following query:
$sql="INSERT INTO images (data_type, title, file_name) "."VALUES('$dataType','$title','$fileName')";
$retval = mysql_query($sql);
///NEW
$size = getimagesize($target_path);
$width=$size[0];
$height=$size[1];
$newwidth = 760;
$newheight = $height*($newwidth/$width);
$pic = new Imagick($target_path);//specify name
$pic->resizeImage($newwidth,$newhight,Imagick::FILTER_LANCZOS,1);
unlink($target_path);
$pic->writeImage($target_path);
$pic->destroy();
///NEW
echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />
<a href='index.php'>Add another image</a><br />";
}
else
{
echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
}
}
} // close your foreach
?>
uploader.php Original code. Allows me to upload 4 images at once. WORKS!!!
<?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");
for($i=0;$i<count($_FILES["image"]["name"]);$i++){
if($_FILES["image"]["name"][$i] != ''){ // don't insert if file name empty
$dataType = mysql_real_escape_string($_POST["dataType"][$i]);
$title = mysql_real_escape_string($_POST["title"][$i]);
$fileData = pathinfo($_FILES["image"]["name"][$i]);
$fileName = uniqid() . '.' . $fileData['extension'];
$target_path = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName;
if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path)){ // The file is in the images/gallery folder.
// Insert record into database by executing the following query:
$sql="INSERT INTO images (data_type, title, file_name) "."VALUES('$dataType','$title','$fileName')";
$retval = mysql_query($sql);
echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />
<a href='index.php'>Add another image</a><br />";
}
else
{
echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
}
}
} // close your foreach
?>
FYI, This will allow you to give a unique names to your images, resize the width, but keep the correct aspect ratio and upload multiple file at the same time.
Awesome Stuff!
Like this:
$filelocation='http://help.com/images/help.jpg';
$newfilelocation='http://help.com/images/help1.jpg';
$size = getimagesize($filelocation);
$width=$size[0];//might need to be ['1'] im tired .. :)
$height=$size[1];
// Plz note im not sure of units pixles? & i could have the width and height confused
//just had some knee surgery so im kinda loopy :)
$newwidth = 760;
$newheight = $height*($newwidth/$width)
$pic = new Imagick( $filelocation);//specify name
$pic->resizeImage($newwidth,$newhight,Imagick::FILTER_LANCZOS,1);
//again might have width and heing confused
$pic->writeImage($newfilelocation);//output name
$pic->destroy();
unlink($filelocation);//deletes image
Here is something kind of similar, lets check the size and compress if the image seems that it is too big. I didn't resize it which just requires that you get the dimensions and resize based on desire.
All this is doing is if the file is greater than 250KB compress it to 85% ..
$bytes = filesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
//$maxSizeInBytes = 26400; //is 250KB? No? compress it.
if ($bytes > 26400) {
$img = new Imagick($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
$img->setImageCompression(imagick::COMPRESSION_JPEG);
$img->stripImage();
$img->setImageCompressionQuality(85);
$img->writeImage($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
}
OR:
// resize with imagejpeg ($image, $destination, $quality); if greater than byte size KB
// Assume only supported file formats on website are jpg,jpeg,png, and gif. (any others will not be compressed)
$bytes = filesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
//$maxSizeInBytes = 26400; //is gtr than 250KB? No? compress it.
if ($bytes > 26400) {
$info = getimagesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
$quality = 85; //(1-100), 85-92 produces 75% quality
if ($info['mime'] == 'image/jpeg') {
$image = imagecreatefromjpeg($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
} elseif ($info['mime'] == 'image/gif') {
$image = imagecreatefromgif($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
} elseif ($info['mime'] == 'image/png') {
$image = imagecreatefrompng($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
}
}
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.