简体   繁体   中英

Sort images by exif data in php

I'm new to php and I'm trying to figure out how to sort images by exif creation date. The code below is the one from this tutorial I followed: Simple Php Gallery Pagination

I just modified a little bit to retrieve exif data I'm looking for a method without database, the goal is to have a paginated gallery (and now it is paginated) sorted with newest first

function getPictures() {
    global $page, $per_page, $has_previous, $has_next, $DirFoto, $DirThumb;
    if ( $handle = opendir($DirFoto) ) {

        echo '<ul id="pictures">';

        $count = 0;
        $skip = $page * $per_page;

        if ( $skip != 0 )
            $has_previous = true;

        while ( $count < $skip && ($file = readdir($handle)) !== false ) {
            if ( !is_dir($file) && ($type = getPictureType($file)) != '' )
                $count++;
        }
        while ( $count < $per_page && ($file = readdir($handle)) !== false ) {
            if ( !is_dir($file) && ($type = getPictureType($file)) != '' ) {

                $exif = exif_read_data("$DirFoto/$file", 0, true);                  

                if ( ! is_dir($DirThumb) ) {
                    mkdir($DirThumb);
                }
                if ( ! file_exists($DirThumb.'/'.$file) ) {
                    makeThumb( $file, $type );
                }
                echo '<li><a href="'.$DirFoto.'/'.$file.'" title="Photo taken on '.date("F d Y, H:i:s", strtotime($exif['IFD0']['DateTime'])).'">';
                    echo '<img src="'.$DirThumb.'/'.$file.'" alt="'.date("F d Y, H:i:s", strtotime($exif['IFD0']['DateTime'])).'"/>';   
                echo '</a></li>';
                $count++;
            }
        }
        echo '</ul>';



        while ( ($file = readdir($handle)) !== false ) {
            if ( !is_dir($file) && ($type = getPictureType($file)) != '' ) {
                $has_next = true;
                break;
            }
        }


    }
}

I rationalized a bit the whole code, and this is my result:

    $ScriptsHead = '
        <link type="text/css" media="screen" rel="stylesheet" href="./stile.css"/>
        <link type="text/css" rel="stylesheet" href="./js/photoswipe.css"/>
        <script type="text/javascript" src="./js/jquery-1.8.3.js"></script>
        <script type="text/javascript" src="./js/klass.min.js"></script>
        <script type="text/javascript" src="./js/code.photoswipe-3.0.5.min.js"></script>
        <script type="text/javascript" src="./js/miophotoswipe.js"></script>            
    ';

function getPictures() {
    global $page, $per_page, $has_previous, $has_next, $DirFoto, $DirThumb;
    if ( $handle = opendir($DirFoto) ) {

        $skip = $page * $per_page;

        $images = array(); # empty data structure
        while(($file = readdir($handle)) !== false ) {
            if($file == '..' || $file == '.' || is_dir($file) || getPictureType($file) == '')
                continue;
            # only for images
            $exif = exif_read_data("$DirFoto/$file", 0, true);
            $date = $exif['IFD0']['DateTime']; # everything you like to be ordered
            $images[$file] = $date; # associate each file to its date
        }
        asort($images); # sort the structure by date

        echo '<ul id="pictures">';

        if ( $skip != 0 )
            $has_previous = true;

        $count = -1;
        foreach ($images as $file => $fileDate) {
            $count ++;
            if($count < $skip)
                continue;
            if($count >= $skip + $per_page) {
                $has_next = true;
                break;
            }

            if ( ! is_dir($DirThumb) ) {
                mkdir($DirThumb);
            }
            if ( ! file_exists($DirThumb.'/'.$file) ) {
                makeThumb( $file, $type );
            }

            echo '<li><a href="'.$DirFoto.'/'.$file.'" title="Photo taken on '.date("F d Y, H:i:s", strtotime($fileDate)).'">';
            echo '<img src="'.$DirThumb.'/'.$file.'" alt="'.date("F d Y, H:i:s", strtotime($fileDate)).'"/>';   
            echo '</a></li>';

        }
        echo '</ul>';
    }


}


    function getPictureType($file) {
        $split = explode('.', $file); 
        $ext = $split[count($split) - 1];
        if ( preg_match('/jpg|jpeg/i', $ext) ) {
            return 'jpg';
        } else if ( preg_match('/png/i', $ext) ) {
            return 'png';
        } else if ( preg_match('/gif/i', $ext) ) {
            return 'gif';
        } else {
            return '';
        }
    }

    function makeThumb( $file, $type ) {
        global $max_width, $max_height, $DirFoto, $DirThumb;
        if ( $type == 'jpg' ) {
            $src = imagecreatefromjpeg($DirFoto.'/'.$file);
        } else if ( $type == 'png' ) {
            $src = imagecreatefrompng($DirFoto.'/'.$file);
        } else if ( $type == 'gif' ) {
            $src = imagecreatefromgif($DirFoto.'/'.$file);
        }
        if ( ($oldW = imagesx($src)) < ($oldH = imagesy($src)) ) {
            $newW = $oldW * ($max_width / $oldH);
            $newH = $max_height;
        } else {
            $newW = $max_width;
            $newH = $oldH * ($max_height / $oldW);
        }
        $new = imagecreatetruecolor($newW, $newH);
        imagecopyresampled($new, $src, 0, 0, 0, 0, $newW, $newH, $oldW, $oldH);
        if ( $type == 'jpg' ) {
            imagejpeg($new, $DirThumb.'/'.$file);
        } else if ( $type == 'png' ) {
            imagepng($new, $DirThumb.'/'.$file);
        } else if ( $type == 'gif' ) {
            imagegif($new, $DirThumb.'/'.$file);
        }
        imagedestroy($new);
        imagedestroy($src);
    }
/*  echo phpinfo(); */

?>

Since the code reads through the directory and outputs HTML as it goes, you will have to change it up a bit to do what you want. I suggest first reading the filenames into an array and call exif_read_data for each file read.

If you key the array by the filename and the value of the array is the exif creation date, you can then call asort() to sort the array by creation date. If a file doesn't have a valid exif creation date, perhaps you could just use the modification time of the file on the server.

Once the array is sorted in the proper order, you could change the following while loop

while ( $count < $per_page && ($file = readdir($handle)) !== false ) {

to be

while ( $count < $per_page && ($file = array_shift($sorted_files)) !== false ) {

where $sorted_files is the array of sorted files. Hope that helps, if not I can try to write up an example.

Sorry I can't try this solution right now, but it should be something like:

<?php

function getPictures() {
    global $page, $per_page, $has_previous, $has_next, $DirFoto, $DirThumb;
    if ( $handle = opendir($DirFoto) ) {

        $images = array(); # empty data structure
        while(($file = readdir($handle)) !== false ) {
            if ( !is_dir($file) && ($type = getPictureType($file)) != '' )
                # only for images
                $exif = exif_read_data("$DirFoto/$file", 0, true);
                $date = $exif['IFD0']['DateTime']; # everything you like to be ordered
                $images[$file] = $date; # associate each file to its date
            }
        }
        asort($images); # sort the structure by date

        echo '<ul id="pictures">';

        $skip = $page * $per_page;

        if ( $skip != 0 )
            $has_previous = true;

        $count = 0;
        while ( $count < $skip && ($file = array_shift($images)) !== false ) {
            if ( !is_dir($file) && ($type = getPictureType($file)) != '' )
                $count++;
        }
        # $count = 0;# (???)
        while ( $count < $per_page && ($file = array_shift($images)) !== false ) {

            $exif = exif_read_data("$DirFoto/$file", 0, true); # it could be avoided                

            if ( ! is_dir($DirThumb) ) {
                mkdir($DirThumb);
            }
            if ( ! file_exists($DirThumb.'/'.$file) ) {
                makeThumb( $file, $type );
            }
            echo '<li><a href="'.$DirFoto.'/'.$file.'" title="Photo taken on '.date("F d Y, H:i:s", strtotime($exif['IFD0']['DateTime'])).'">';
            echo '<img src="'.$DirThumb.'/'.$file.'" alt="'.date("F d Y, H:i:s", strtotime($exif['IFD0']['DateTime'])).'"/>';   
            echo '</a></li>';

            $count++;
        }
        echo '</ul>';



        while ( ($file = readdir($handle)) !== false ) {
            if ( !is_dir($file) && ($type = getPictureType($file)) != '' ) {
                $has_next = true;
                break;
            }
        }


    }
}
?>

Please give me a feedback on that. Cheers, Riccardo

The code works now, if I mouseover the tooltip shows me the right date but no thumbnails or images are loaded. In my first question I omitted the last two functions, this is my current update code:

<?php
    $page = $_GET['page'];
    $has_previous = false;
    $has_next = false;  
function getPictures() {
    global $page, $per_page, $has_previous, $has_next, $DirFoto, $DirThumb;
    if ( $handle = opendir($DirFoto) ) {
        $images = array();
        while(($file = readdir($handle)) !== false ) {
            if ( !is_dir($file) && ($type = getPictureType($file)) != '' )

                $exif = exif_read_data("$DirFoto/$file", 0, true);
                $date = $exif['IFD0']['DateTime'];
                $images[$file] = $date;
            }
        }
        asort($images);

        echo '<ul id="pictures">';
        $skip = $page * $per_page;
        if ( $skip != 0 )
            $has_previous = true;

        $count = 0;
        while ( $count < $skip && ($file = array_shift($images)) !== false ) {
            if ( !is_dir($file) && ($type = getPictureType($file)) != '' )
                $count++;
        }
        while ( $count < $per_page && ($file = array_shift($images)) !== false ) {
            $exif = exif_read_data("$DirFoto/$file", 0, true);              

            if ( ! is_dir($DirThumb) ) {
                mkdir($DirThumb);
            }
            if ( ! file_exists($DirThumb.'/'.$file) ) {
                makeThumb( $file, $type );
            }
            echo '<li><a href="'.$DirFoto.'/'.$file.'" title="Photo taken on '.date("F d Y, H:i:s", strtotime($exif['IFD0']['DateTime'])).'">';
            echo '<img src="'.$DirThumb.'/'.$file.'" alt="'.date("F d Y, H:i:s", strtotime($exif['IFD0']['DateTime'])).'"/>';   
            echo '</a></li>';

            $count++;
        }
        echo '</ul>';
        while ( ($file = readdir($handle)) !== false ) {
            if ( !is_dir($file) && ($type = getPictureType($file)) != '' ) {
                $has_next = true;
                break;
            }
        }


    }

    function getPictureType($file) {
        $split = explode('.', $file); 
        $ext = $split[count($split) - 1];
        if ( preg_match('/jpg|jpeg/i', $ext) ) {
            return 'jpg';
        } else if ( preg_match('/png/i', $ext) ) {
            return 'png';
        } else if ( preg_match('/gif/i', $ext) ) {
            return 'gif';
        } else {
            return '';
        }
    }
    function makeThumb( $file, $type ) {
        global $max_width, $max_height;
        if ( $type == 'jpg' ) {
            $src = imagecreatefromjpeg($DirFoto.'/'.$file);
        } else if ( $type == 'png' ) {
            $src = imagecreatefrompng($DirFoto.'/'.$file);
        } else if ( $type == 'gif' ) {
            $src = imagecreatefromgif($DirFoto.'/'.$file);
        }
        if ( ($oldW = imagesx($src)) < ($oldH = imagesy($src)) ) {
            $newW = $oldW * ($max_width / $oldH);
            $newH = $max_height;
        } else {
            $newW = $max_width;
            $newH = $oldH * ($max_height / $oldW);
        }
        $new = imagecreatetruecolor($newW, $newH);
        imagecopyresampled($new, $src, 0, 0, 0, 0, $newW, $newH, $oldW, $oldH);
        if ( $type == 'jpg' ) {
            imagejpeg($new, $DirThumb.'/'.$file);
        } else if ( $type == 'png' ) {
            imagepng($new, $DirThumb.'/'.$file);
        } else if ( $type == 'gif' ) {
            imagegif($new, $DirThumb.'/'.$file);
        }
        imagedestroy($new);
        imagedestroy($src);
    }
?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM