Log in

View Full Version : Photo Album 2.1 Image date



pellsonline
09-07-2013, 01:20 PM
I am using php photo album and it works great.

I am using the autodesc option %d to display date.

This displays the date the image was last modified.

I have modified the getalbumpics.php file to remove hour, minutes and seconds and display mm/dd/yyy



My question is: can I display the date the image was created?

Thank you

jscheuer1
09-07-2013, 01:54 PM
If the image has EXIF data which many cameras, software and other devices create automatically and that data contains that information and the EXIF data has been preserved (many image editing programs can strip it to save on bytes), you can use that. See:

http://stackoverflow.com/questions/13674296/getting-taken-date-of-a-photo-instead-of-modified-date-with-php-exif-read-da

and:

http://www.php.net/manual/en/function.exif-read-data.php

If that's not enough info for you to adapt your PHP code to get what you want, let me know. But, as I say, if the EXIF data isn't there or doesn't contain that information, you cannot get it.

Oh, and some image editing programs allow you to create such data if it wasn't originally saved or was stripped. But at that point you have to be able to remember when the image was created or be able to retrieve the info from an original version that might still have it.

pellsonline
09-07-2013, 03:05 PM
Thanks John,

My images are all recent digital camera so they should have EXIF data.

I am a novice and really not up on coding. I can usually work it out by trial & error.

This is the original code:

<?
Header("content-type: application/x-javascript");

function returnimages($dirname=".") {
$pattern="\.(jpg|jpeg|png|gif|bmp)$";
$files = array();
$curimage=0;
if($handle = opendir($dirname)) {
while(false !== ($file = readdir($handle))){
if(eregi($pattern, $file)){
$filedate=date ("M d, Y", filemtime($file));
echo " [$curimage, \"$file\", \"$filedate\"],\n";
$curimage++;
}
}
echo " [\"placeholder\"]\n";
closedir($handle);
}
return($files);
}

$photovar=$_GET['id'];
if (!eregi("^[a-zA-Z0-9_]+$", $photovar)){
echo "alert(\"Photo Album ID must contain only letters, numbers, or underscore, and cannot start with a number\")";
die();
}
echo "var $photovar={\n";
echo " baseurl: \"http://" . $_SERVER["SERVER_NAME"] . dirname($_SERVER['PHP_SELF']) . "/\",\n";
echo " images: [\n";
returnimages();
echo " ],\n";
echo " desc: []\n";
echo "}\n";
?>


I have tried making changes described in the two links you send me but can't figure it out. Can you just point me to the area to change?

Thanks,
Joe

jscheuer1
09-07-2013, 04:09 PM
I tried this out in a simplified version and it worked:


<?php
$exif = exif_read_data('PICT0002.JPG');
echo date("m/d/Y", $exif['FileDateTime']);
?>

But I had to enable exif first. That may or may not be an issue with your server. If it is, see:

http://www.rudibela.com/web-development/php/php-exif-extension/

Assuming something like that works, this might be good for the getalbumpics.php file:


<?
Header("content-type: application/x-javascript");

function returnimages($dirname=".") {
$pattern="\.(jpg|jpeg|png|gif|bmp)$";
$files = array();
$curimage=0;
if($handle = opendir($dirname)) {
while(false !== ($file = readdir($handle))){
if(eregi($pattern, $file)){
$filedate=date ("M d, Y", filemtime($file));
$exif = exif_read_data($file);
if($exif) {echo " [$curimage, \"$file\", \"" . date("M d, Y", $exif['FileDateTime']) . "\"],\n";}
else {echo " [$curimage, \"$file\", \"$filedate\"],\n";}
$curimage++;
}
}
echo " [\"placeholder\"]\n";
closedir($handle);
}
return($files);
}

$photovar=$_GET['id'];
if (!eregi("^[a-zA-Z0-9_]+$", $photovar)){
echo "alert(\"Photo Album ID must contain only letters, numbers, or underscore, and cannot start with a number\")";
die();
}
echo "var $photovar={\n";
echo " baseurl: \"http://" . $_SERVER["SERVER_NAME"] . dirname($_SERVER['PHP_SELF']) . "/\",\n";
echo " images: [\n";
returnimages();
echo " ],\n";
echo " desc: []\n";
echo "}\n";
?>


The browser cache may need to be cleared and/or the page refreshed to see changes.

If you want more help, please include a link to the page on your site that contains the problematic code so we can check it out.

pellsonline
09-07-2013, 08:32 PM
John,

Tried your suggestion with no success.

I double checked that I loaded your code correctly.

This is the link to the page on my site that I am using as a test. http://www.claragraceroman.com/album0206.htm

I ran info.php on my site and appears that EXIF is enabled for JPEG & TIFF (sensitive link removed) so I opened the three test images and saved them as JPEG.
When you look at the page you will see that the images are duplicated. One is jpg the other JPEG so I guess that doesn't matter.

I found this routine online that displays the EXIF data and the date taken is there. http://regex.info/exif.cgi

Joe

jscheuer1
09-08-2013, 01:48 AM
I'm still not convinced EXIF is working on the server.

First off, the file extension (.jpg, .jpeg, .JPG, .JPEG) doesn't matter, as long as it's a JPG image.

Next - You should never link to your phpinfo() in a public forum. It's an invitation to hackers. (I've removed the link from your post for your protection)

Not being a hacker myself, it doesn't help me much other than I do know from trying this out on my WAMP server that EXIF can be enabled but not functional unless mbstring is enabled as well and that mbstring must be enabled before EXIF in the php.ini file, ex:


extension=php_mbstring.dll
extension=php_exif.dll

If possible, check the server's php.ini to make sure they appear in the correct order. From your info.php page, it looks like they might not be, as exif appears before mbstring in the Configure Command section.

As another sort of test, try this standalone page (I tried this on my WAMP server):


<!DOCTYPE html>
<html>
<head>
<title>EXIF Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<script type="text/javascript">
document.write(new Date('<?php
$exif = exif_read_data('http://www.claragraceroman.com/images/album0206/017.jpg');
echo date("M d, Y", $exif['FileDateTime']);
?>'));
</script>
</body>
</html>



and got:


Wed Dec 31 1969 00:00:00 GMT-0500 (Eastern Standard Time)

That means that at least that file has EXIF data including its FileDateTime property. As to whether or not your server will report it is what we are trying to determine. So host the above file on your server as - say textexif.php, and see what it gets you.

If that checks out, I have complete remake of the getpics PHP code that test out OK here using EXIF, so let me know.

pellsonline
09-09-2013, 03:46 PM
John,

Did what you asked with same result (Wed Dec 31 1969 00:00:00 GMT-0500 (Eastern Standard Time))
This test picture was actually taken Aug, 6, 2013

I also tried it with an image I took this morning with same result of Dec 31, 1969

Also contacted server and ask if EXIF is configured properly but have not yet received a response.

Joe

jscheuer1
09-09-2013, 06:01 PM
OK, that actually means EXIF is working, I checked another way:


<!DOCTYPE html>
<html>
<head>
<title>EXIF Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>

<?php
$exif = exif_read_data('http://www.claragraceroman.com/images/album0206/017.jpg');
echo $exif['FileDateTime'];
?>

</body>
</html>



I got:

0

Which (in PHP and in javascript) is that EST date. That means the EXIF FileDateTime for that file is 0. I checked the full EXIF and it is. It reports the camera as iPhone. So I guess it doesn't save that. I have a Konica Minolta that does, so I was going on that. The EXIF from that image does have an accurate value for DateTimeOriginal, but it's in a different format.

So we can do:


<!DOCTYPE html>
<html>
<head>
<title>EXIF Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<script type="text/javascript">
var d0 = '<?php
$exif = exif_read_data('http://www.claragraceroman.com/images/album0206/017.jpg');
echo $exif['DateTimeOriginal'];
?>'.split(/[ :]/g);
document.write(new Date(d0[0], --d0[1], d0[2], d0[3], d0[4], d0[5]));
</script>
</body>
</html>



and get:


Tue Aug 06 2013 06:47:29 GMT-0400 (Eastern Daylight Time)

Which I think is what we are after. If so this should work as the getalbumpics.php file:


<?php
Header("content-type: application/x-javascript");
function returnimages(){
$photovar = isset($_GET['id'])? $_GET['id'] : 'galleryarray';
if (!preg_match('#^[a-z_][a-z0-9_]+$#i', $photovar)){
echo 'alert("id/array name must be at least two characters and contain only letters, numbers, or underscore, and cannot start with a number")';
die();
}
$path = str_replace(' ', '%20', str_replace($_SERVER['DOCUMENT_ROOT'], '', str_replace('\\', '/', getcwd())));
$base = '//' . preg_replace('#/{2,}#', '/', "{$_SERVER["SERVER_NAME"]}/$path/");
$dirname = '.';
$pattern = '#\.(jpg|jpeg|png|gif|bmp)$#i';
if($handle = opendir($dirname)){
clearstatcache();
while(false !== ($file = readdir($handle))){
if(preg_match($pattern, $file)){
@$filedate = exif_read_data($file);
if($filedate && isset($filedate['DateTimeOriginal'])){
$filedate = strtotime($filedate['DateTimeOriginal']);
} else { $filedate = filemtime($file); }
$files[$file] = $filedate;
}
}
closedir($handle);
}
arsort($files, SORT_NUMERIC);
$count = -1;
foreach ($files as $file => $time){
$jsarray[] = "[" . ++$count . ", '$file', '" . date("M d, Y", $time) . "']";
}
return "var $photovar = {\n\tbaseurl: '$base',\n\timages: [\n\t\t" . implode(",\n\t\t", $jsarray) . ",\n\t\t['placeholder']\n\t],\t\n\tdesc: []\n};";
}

echo returnimages();
die();
?>



BTW, as long as all of the images have this data, it already sorts the files in order from newest to oldest, so you don't have to sort them in the javascript part. But you can, it shouldn't hurt anything. But if not all of the images have that data, then those that don't will use the filetime timestamp, so will appear more recent (time of upload) in either a javascript or PHP sort.

If you don't have javascript sort the dates, you can get a little more creative in formatting them in PHP, like - "M jS, Y", which would give you dates like - Aug 6th, 2013.

The browser cache may need to be cleared and/or the page refreshed to see changes.

Note: The line:


$filedate = strtotime($filedate['DateTimeOriginal']);

or other minor parts of the PHP code might have to be expanded upon, changed or even replaced by a few lines of code for your version of PHP.

pellsonline
09-10-2013, 05:13 PM
John,

I set up a test file containing five images that I know contain the date info and they display exactly as I would like.
http://claragraceroman.com/test.html

Only problem is the images don't display. I reviewed your code but can't figure it out.

Joe

jscheuer1
09-10-2013, 05:53 PM
OK, that was left over from a bit of fanciness I had in that code. It's getting the wrong base URL for the images. Use this simplified version:


<?php
Header("content-type: application/x-javascript");
function returnimages(){
$photovar = isset($_GET['id'])? $_GET['id'] : 'galleryarray';
if (!preg_match('#^[a-z_][a-z0-9_]+$#i', $photovar)){
echo 'alert("id/array name must be at least two characters and contain only letters, numbers, or underscore, and cannot start with a number")';
die();
}
$base = "//" . $_SERVER["SERVER_NAME"] . dirname($_SERVER['PHP_SELF']) . "/";
$dirname = '.';
$pattern = '#\.(jpg|jpeg|png|gif|bmp)$#i';
if($handle = opendir($dirname)){
clearstatcache();
while(false !== ($file = readdir($handle))){
if(preg_match($pattern, $file)){
@$filedate = exif_read_data($file);
if($filedate && isset($filedate['DateTimeOriginal'])){
$filedate = strtotime($filedate['DateTimeOriginal']);
} else { $filedate = filemtime($file); }
$files[$file] = $filedate;
}
}
closedir($handle);
}
arsort($files, SORT_NUMERIC);
$count = -1;
foreach ($files as $file => $time){
$jsarray[] = "[" . ++$count . ", '$file', '" . date("M jS, Y", $time) . "']";
}
return "var $photovar = {\n\tbaseurl: '$base',\n\timages: [\n\t\t" . implode(",\n\t\t", $jsarray) . ",\n\t\t['placeholder']\n\t],\t\n\tdesc: []\n};";
}

echo returnimages();
die();
?>



The browser cache may need to be cleared and/or the page refreshed to see changes.

If you're interested, that other version was for a file that could get the images from any folder. It used the getcwd() function, which apparently introduces port numbers or something into the URL. I've now switched back to what was used in the original for that part.

pellsonline
09-10-2013, 06:55 PM
John,
That is terrific. Thanks so much.
As you can tell I am a novice concerning code. I can build a fair site using "canned" scripts and modify basics.

I built this site for my granddaughter who is visually impaired. I wanted her mother & father to be able to upload images for family & friends.

Can't thank you enough.

Regards,
Joe

pellsonline
09-10-2013, 09:03 PM
John,

This is exactly what I wanted to do!
I am interested in the other version and will fool around with it as I learn more code.
I'm a novice regarding code but have managed to build a couple of decent web sites using "canned" scripts and modifying basics.

My granddaughter is visually impaired so I built this site and wanted her mother & father to be able to upload pictures for family & friends.
I can't thank you enough for the time and effort you put into this to help me.

Regards,
Joe

jscheuer1
09-10-2013, 09:36 PM
I'm not sure what other version you're referring to. If you mean the one that I said can open any folder, that's not exactly what it was. It had some code left over from that and that code was causing a problem on your server, so I reverted that part to the original. If you mean the first one I gave you, that one could probably be modified to work using the DateTimeOriginal property of the EXIF.

If you want the full version of the one that can open any folder, let me know. There might be a way to get it work. I'm thinking that, as long as the network path is given to it as a parameter in the query string, it could just use that as the baseurl.

But I'm not sure how secure it is. Someone could use it to read the images in any folder on the server. I guess that's not a real big deal on the site you're using it on, but it could be for some sites.

Oh, at least one other thing has occurred to me off and on with this concept. Like with the FileDateTime property, which was 0 on your iPhone images, it's possible that could happen with the DateTimeOriginal property, in which case you would get that date in late Dec, 1969 I think it was, or Jan 1 1970, as I think we are doing this all server side now. In any case, there's a way to avoid that here:


if($filedate && isset($filedate['DateTimeOriginal'])){

By adding:


if($filedate && isset($filedate['DateTimeOriginal']) && $filedate['DateTimeOriginal'] > 0){

But of course it will then default to filetime(). Still better than an inaccurate date so far in the past.

I believe that using PHP or an image utility, you can set EXIF values if they're lost or wrong. I know you can set at least some of them. I'm not sure if you can set the DateTimeOriginal though.