Как я могу ускорить этот скрипт, я использую PHP GD

У меня проблемы со сценарием, который слишком долго генерировал миниатюры на ноутбуке моих друзей. Я выделил 2 ГБ памяти для сценария, вот "тесты".

  • Перемещение файла заняло -0,101 минуты: 038.JPG
    • Взял -4.638 для загрузки изображения в память и -6.093 для изменения размера: 038.JPG
      • Взял -0,042, чтобы добавить информацию об изображении в базу данных!
  • Перемещение файла заняло -0,054 минуты: 039.JPG
    • Взял -4.670 для загрузки изображения в память и -5.720 для изменения размера: 039.JPG
      • Взял -0,079, чтобы добавить информацию об изображении в базу данных! Взял -0.000 для перемещения и создания миниатюр всех файлов. Взял -24.619 для запуска всего скрипта.

Процессор: AMD E1-1200 - 1,40 ГГц. Память: 4,00 ГБ.

Ниже приведен PHP-скрипт (не самый чистый из кода), в основном он перемещает файлы из одной папки в другую, а также создает эскизы версий. В настоящее время я проверил это на 2 изображениях, но по моим расчетам, если бы я должен был сделать это для 100 изображений (что происходит в большинстве случаев), это займет около 25 минут, что недопустимо!

Изображения имеют разрешение 4512px x 3000px и имеют размер около 3,62 МБ.

<?php
session_start();
$run_start = microtime(true);
header("Cache-Control: no-cache, must-revalidate"); //HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); //Date in the past

//Make additional session keys
$_SESSION['ROOT_DIR'] = "http://".$_SERVER['HTTP_HOST']."/ppa/";
$_SESSION['ROOT_PATH'] = $_SERVER['DOCUMENT_ROOT']."/ppa/";

//Includes
include "../includes/db_connect.php";
include "../includes/required.php";

//$drive = $_POST['drive'];
$drive = $_GET['x'];

if (isset($drive)) {
    $x = explode("_", $drive);
    $x = $x[1];

    //Need to connect to database to see which upload number this will be
    if ($stmt = $mysqli->prepare("SELECT imageset FROM images WHERE udate = ? ORDER BY id DESC LIMIT 1")) {
        $stmt->bind_param('s', $_SESSION['session_date']);
        $stmt->execute(); //Execute the query
        $stmt->store_result();
        $stmt->bind_result($folder); //get variables from result
        $stmt->fetch();
        if ($stmt->num_rows != 1) { //result is returned
            $folder = -1;
        }
        $folder = $folder+1;
        //Set session variable for the progress bar
        //$_SESSION['tmp'] = $x."_".$folder;

        //Checks complete, now process the upload
        $files = scandir($x.":/DCIM/");

        // Identify directories
        $source = $x.":/DCIM/";
        $destination = $_SESSION['ROOT_PATH']."data/images/".str_replace("/","",$_SESSION['session_date'])."/".$folder."/";
        if (count($files) > 2) {
            //Create folders
            if(!is_dir($_SESSION['ROOT_PATH']."data/images/".str_replace("/","",$_SESSION['session_date'])."/")) {
                mkdir($_SESSION['ROOT_PATH']."data/images/".str_replace("/","",$_SESSION['session_date'])."/");}

            if(!is_dir($_SESSION['ROOT_PATH']."data/images/".str_replace("/","",$_SESSION['session_date'])."/".$folder."/")) {
                mkdir($_SESSION['ROOT_PATH']."data/images/".str_replace("/","",$_SESSION['session_date'])."/".$folder."/");}

            if(!is_dir($_SESSION['ROOT_PATH']."data/images/".str_replace("/","",$_SESSION['session_date'])."/".$folder."/thumb/")) {
                mkdir($_SESSION['ROOT_PATH']."data/images/".str_replace("/","",$_SESSION['session_date'])."/".$folder."/thumb/");}

            // Delete all successfully-copied files
            function delete($del) {
                if (isset($del) && count($del) > 0) {
                    foreach ($del as $file) {
                      (!is_dir($file)) ? unlink($file) : "";
                    }
                }
            }
            // Cycle through all source files
            //Remove PHP time limites and memory limits to process high res photos
            ini_set('memory_limit', '-1'); 
            set_time_limit(0);

            $move_resize = function($files,$source,$destination,$settings,$mysqli,$folder) {
                foreach ($files as $file) {
                    if (in_array($file, array(".",".."))) continue;

                    //Check if the file is a directory
                    if (is_dir($source.$file)) {
                        //This is a directory
                        $new_dir[] = $file;
                    } else {
                        //Check that the filename isn't too long
                        if (strlen($file) > 100) {
                            $ext = explode(".",$file);
                            $tmp = str_split($file, (100-strlen($ext[1])-1));
                            $file = $tmp[0].".".$ext[1];
                        }

                        // If we copied this successfully, mark it for deletion
                        $move_start = microtime(true);
                        if (copy($source.$file, $destination.$file)) {
                            //allow all memory to be used, bad practice, but large photos need it!  
                            $move_end = microtime(true);
                            echo "- Took ".number_format($move_start - $move_end,3)." minutes to move file: ".$file."<br />";

                            $loadintmem_start = microtime(true);
                            $im = imagecreatefromjpeg($source.$file);
                            $loadintmem_end = microtime(true);

                            //Create image thumbnail, width and height
                            $ratio = $settings['system']['thumb_size'] / imagesx($im);
                            $width = $settings['system']['thumb_size'];
                            $height = imagesy($im) * $ratio;

                            $thumb_start = microtime(true);
                            //Create thumbnail container
                            $thumb = imagecreatetruecolor($width,$height);
                            imagecopyresampled($thumb,$im,0,0,0,0,$width,$height,imagesx($im),imagesy($im));
                            imagejpeg($thumb,$destination."thumb/".$file);      

                            //Free up memory
                            imagedestroy($im);
                            imagedestroy($thumb);

                            $thumb_end = microtime(true);

                            $delete[] = $source.$file; //Add to deletion list

                            echo "- - Took ".number_format($loadintmem_start - $loadintmem_end,3)." to load image into memory and ".number_format($thumb_start - $thumb_end,3)." to resize for: ".$file." <br />";

                            //Get additional image data
                            $udatetime = $_SESSION['session_date']." ".date('G:i:s');
                            $file_data = exif_read_data($source.$file);
                            $takendatetime = date("o/m/d G:i:s",$file_data['FileDateTime']);

                            //Add to database
                            $database_start = microtime(true);

                            $sql = "INSERT INTO images (jpg,udate,imageset,dodelete,sold,takendatetime,udatetime,venue) VALUES (?,?,?,?,?,?,?,?)";
                            $dodelete = 0; $sold = 0;
                            if($stmt = $mysqli->prepare($sql)) {
                                $stmt->bind_param('ssiiisss',$file,$_SESSION['session_date'],
                                $folder,$dodelete,$sold,$takendatetime,$udatetime,str_replace(" ","",strtolower($_SESSION['venue'])));

                                $stmt->execute();
                                $stmt->close();
                            } else {
                                echo "Unable to copy images (prepare failed) ".$mysqli->error;  
                            }

                            $database_end = microtime(true);
                            echo "- - - Took ".number_format($database_start - $database_end,3)." to add image information to database! <br />";
                        }
                    }
                }
                return array($delete,$new_dir);
            };
            //Move images from main directory, then check for sub directories
            $primary = $move_resize($files,$source,$destination,$settings,$mysqli,$folder);

            //Phase results
            $new_dir = $primary[1]; //Directories
            $delete = $primary[0]; //Files to delete
            delete($delete); //Delete files
            unset($delete);

            $proc_start = microtime(true);

            if (count($new_dir) > 0) {
                $directories = $new_dir; unset($new_dir);
                foreach($directories as $current_dir) {
                    $files = scandir($x.":/DCIM/".$current_dir."/");
                    $source = $x.":/DCIM/".$current_dir."/";
                    if (count($files) > 0) {
                        $new = $move_resize($files,$source,$destination,$settings,$mysqli,$folder);
                    }
                    //Phase results
                    $delete = $new[0]; //Files to delete

                    //Enable subdirectory to be deleted

                    chmod($source, 755);
                    $delete[] = $source; //Add subdirectory to delete
                    delete($delete); //Delete files
                    unset($delete);
                }
            }
            $proc_end = microtime(true);
            echo "Took ".number_format($proc_start - $proc_end,3)." to move and create thumbnails of all files. <br />";

            //Complete
            //$_SESSION['tmp'] = "true";
            //header("Location: ".$_SESSION['ROOT_DIR']."index.php?message=\"Upload complete!\"");
        }
    } else {
        header("Location: ".$_SESSION['ROOT_DIR']."/php/search_drives.php?message=".$error);
        $error = "Prepare failed: (".$mysqli->errno.") ".$mysqli->error;
    }
}
$run_end = microtime(true);
echo "Took ".number_format($run_start - $run_end,3) ." to run entire script. <br />";
?>

Редактировать:

Собираясь попробовать ImageMaick, наконец-то удалось установить его после поиска dll-файла, который, я должен сказать, тупо трудно удержать...

По какой-то причине я получаю следующую ошибку:

Ошибка при создании эскиза: UnableToOpenBlob `032.JPG': нет такого файла или каталога @ error/blob.c/OpenBlob/2642

Вот некоторая информация, чтобы показать, что она установлена ​​правильно:

Array
(
    [GD Version] => bundled (2.1.0 compatible)
    [FreeType Support] => 1
    [FreeType Linkage] => with freetype
    [T1Lib Support] => 
    [GIF Read Support] => 1
    [GIF Create Support] => 1
    [JPEG Support] => 1
    [PNG Support] => 1
    [WBMP Support] => 1
    [XPM Support] => 1
    [XBM Support] => 1
    [JIS-mapped Japanese Font Support] => 
)

И вот код, который я пытался создать миниатюру:

<?php
try {
    $imagick = new Imagick();
    $imagick->readImage('032.JPG');
    $imagick->thumbnailImage(800, 800);
    $imagick->writeImage('032(2).JPG');
}
catch(Exception $e) {
    die('Error when creating a thumbnail: ' . $e->getMessage());
}
?>

Как вы можете видеть на скриншоте ниже, скрипт и изображение находятся в одном каталоге!введите описание изображения здесь

0 ответов

Другие вопросы по тегам