Скрипт по нанесению текста на изображение.


iccup
146

<?php 

    $text = $_GET['text']; //Забираем тест
        // split text parts
        $txtparts = explode("|", $text);
        if(!empty(trim($txtparts[0])) && !empty(trim($txtparts[1])) && !empty(trim($txtparts[2])) && !empty(trim($txtparts[3]))){

    $imgage_path = "img/".trim($txtparts[3]); //Путь к изображению

        $words = explode(" ", trim($txtparts[0]));
        if(count($words) > 5){
                $txt[1] = '';
                $txt[2] = '';
                $txt[3] = '';
                $txt[4] = '';
                for ($i = 0; $i < count($words); $i++) {
                        if($i < 4) $txt[1] .= $words[$i]." ";
                        if($i >= 4 && $i < 8) $txt[2] .= $words[$i]." ";
                        if($i >= 14 && $i < 21) $txt[3] .= $words[$i]." ";
                        if($i >= 21 && $i < 29) $txt[4] .= $words[$i]." ";                      
                } // end FOR
                $txt[1] = mb_substr($txt[1], 0, -1);
                $txt[2] = mb_substr($txt[2], 0, -1);
                $txt[3] = mb_substr($txt[3], 0, -1);
                $txt[4] = mb_substr($txt[4], 0, -1);                                            
            $font_size = 182; // размер шрифта
                if(!empty(trim($txt[4]))){$lines = 4;}
                elseif(!empty(trim($txt[3]))){$lines = 3;}              
                elseif(!empty(trim($txt[2]))){$lines = 2;}
                else{$lines = 1;}
        } else {
                $txt[1] = trim($txtparts[0]);
            $font_size = 200; // размер шрифта 
                $lines = 1;
        }

    $img = imagecreatefromjpeg($imgage_path); // создаём новое изображение из файла
    $font = "fonts/NIRMALAB.TTF"; // путь к шрифту      
    $color = imageColorAllocate($img, 255, 255, 255); //Цвет шрифта
    $shadow = imageColorAllocate($img, 0, 0, 0); // цвет обводки (черный цвет)

        // author font
    $afont = "fonts/NIAGSOL.TTF"; // путь к шрифту author
    $afont_size = 72; // размер шрифта author
    $acolor = imageColorAllocate($img, 255, 255, 255); //Цвет шрифта author

        // mocah font
    $mfont = "fonts/FREESCPT.TTF"; // путь к шрифту author
    $mfont_size = 72; // размер шрифта author
    $mcolor = imageColorAllocate($img, 255, 0, 0); //Цвет шрифта author

    $size=getimagesize($imgage_path); //Узнаем размер изображения
    $w=(int)$size[0]; // ширина
    $h=(int)$size[1]; // высота
        
    // текст по центру 
        $boxgen = imagettfbbox($font_size, 0, $font, $txt[1]);
        $t = ($h/2) - $lines * (($boxgen[3]-$boxgen[5]) / 2 + 140);
        for ($i = 1; $i <= $lines; $i++) {
                $box = imagettfbbox($font_size, 0, $font, $txt[$i]);
                $x = ($w/2)-($box[2]-$box[0])/2; //по оси x
                #$y = ($h/2)-($box[3]-$box[5])/2; //по оси y
                $y = $t + (($box[3]-$box[5])/2)*$i + 140*$i;
                
                //Обводка 
                imagettftext($img, $font_size, 0, $x+2, $y, $shadow, $font, $txt[$i]);
                imagettftext($img, $font_size, 0, $x, $y+2, $shadow, $font, $txt[$i]);
                //Разметка самого текста
                imagettftext($img, $font_size, 0, $x, $y, $color, $font, $txt[$i]);             
        } // end FOR    


        //Author
    $abox = imagettfbbox($afont_size, 0, $afont, trim($txtparts[1]));
    $ax = ($w/2)-($abox[2]-$abox[0])/2; //по оси x
    $ay = ($h)-($abox[3]-$abox[5])/2; //по оси y        
    imagettftext($img, $afont_size, 0, $ax, $ay, $acolor, $afont, trim($txtparts[1]));

        //аа
    $mbox = imagettfbbox($mfont_size, 0, $mfont, trim($txtparts[2]));
    $mx = ($w/2)-($mbox[2]-$mbox[0])/2; //по оси x
    $my = ($h)-($mbox[3]-$mbox[5])/2 - 120; //по оси y  
    imagettftext($img, $mfont_size, 0, $mx, $my, $mcolor, $mfont, trim($txtparts[2]));  
        
        imagejpeg($img, "1.jpg");
    imagedestroy($img);

        $url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
        $url = str_replace("i.php", "1.jpg", $url);
        header('Location: '.$url);
        } // end IF !emprt
?>

вот такой скриптик, все хорошо. но в многопотоке получается каша, скрипт создает временный файл в корне 1.jpg.  Допустим, 2 человека обратятся к нему одновременно, а файл то один. Как сделать чтоб он просто отдавал картинку?


silicoid

 imagejpeg($img, "1.jpg");

Замените на

$new_filename =  md5( rand( 0,time()) ).".jpg";
imagejpeg($img, $new_filename );

// ну и соответственно
$url = str_replace("i.php", $new_filename, $url);

А вообще надо бы по-хорошему мануалы на пы-хы-пы  почитать.

АПД
Причина сего совета проста.
если у вас будет 1 запрос, ок ручками удалите…  А если будет 500 000?
У вас тупо ляжет сервак из-за переполнения файлового буфера операционной системы.

поэтому создавать надо файл в памяти и выдавать его из памяти, а после выполнения скрипта память очищать.

см. первый пример к мануалу
https://www.php.net/manual/en/function.imagejpeg.php


iccup

Работает! Спасибо. Этот скрипт больше для личного пользования, потоков будет немного.


silicoid

iccup #:
Работает! Спасибо. Этот скрипт больше для личного пользования, потоков будет немного.

тут дело в том, что любое дерганье скрипта приведет к созданию нового файла. Чтобы этого не было нужно поступить следующим образом

$new_filename =  md5( $text ) . ".jpg";

Привязать имя файла к GET запросу
и еще можно сделать проверочку вида

//вставить после $text = $_GET['text']; 

$new_filename =  md5($text).".jpg";
if ( file_exists( $new_filename ))
{
        $url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
        $url = str_replace("i.php", $new_filename, $url);
        header('Location: '.$url);
        die(); /* или любой другой способ прервать выполнение функции, если это функция */
}

ну и ессно убрать присвоение имени внизу
тогда имя файла будет строго привязано к гет запросу и если запрос повторяется, то файл будет браться сразу с диска пропуская процесс создания. То-есть диск будет работать как кэш.


iccup

<?php 

    $text = $_GET['text']; //Забираем тест
        // split text parts
        $new_filename =  md5($text).".jpg";
if ( file_exists( $new_filename ))
{
        $url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
        $url = str_replace("i.php", $new_filename, $url);
        header('Location: '.$url);
        die(); /* или любой другой способ прервать выполнение функции, если это функция */
}
        $txtparts = explode("|", $text);
        if(!empty(trim($txtparts[0])) && !empty(trim($txtparts[1])) && !empty(trim($txtparts[2])) && !empty(trim($txtparts[3]))){

    $imgage_path = "img/".trim($txtparts[3]); //Путь к изображению

        $words = explode(" ", trim($txtparts[0]));
        if(count($words) > 5){
                $txt[1] = '';
                $txt[2] = '';
                $txt[3] = '';
                $txt[4] = '';
                for ($i = 0; $i < count($words); $i++) {
                        if($i < 4) $txt[1] .= $words[$i]." ";
                        if($i >= 4 && $i < 8) $txt[2] .= $words[$i]." ";
                        if($i >= 14 && $i < 21) $txt[3] .= $words[$i]." ";
                        if($i >= 21 && $i < 29) $txt[4] .= $words[$i]." ";                      
                } // end FOR
                $txt[1] = mb_substr($txt[1], 0, -1);
                $txt[2] = mb_substr($txt[2], 0, -1);
                $txt[3] = mb_substr($txt[3], 0, -1);
                $txt[4] = mb_substr($txt[4], 0, -1);                                            
            $font_size = 182; // размер шрифта
                if(!empty(trim($txt[4]))){$lines = 4;}
                elseif(!empty(trim($txt[3]))){$lines = 3;}              
                elseif(!empty(trim($txt[2]))){$lines = 2;}
                else{$lines = 1;}
        } else {
                $txt[1] = trim($txtparts[0]);
            $font_size = 200; // размер шрифта 
                $lines = 1;
        }

    $img = imagecreatefromjpeg($imgage_path); // создаём новое изображение из файла
    $font = "fonts/NIRMALAB.TTF"; // путь к шрифту      
    $color = imageColorAllocate($img, 255, 255, 255); //Цвет шрифта
    $shadow = imageColorAllocate($img, 0, 0, 0); // цвет обводки (черный цвет)

        // author font
    $afont = "fonts/NIAGSOL.TTF"; // путь к шрифту author
    $afont_size = 72; // размер шрифта author
    $acolor = imageColorAllocate($img, 255, 255, 255); //Цвет шрифта author

        // mocah font
    $mfont = "fonts/FREESCPT.TTF"; // путь к шрифту author
    $mfont_size = 72; // размер шрифта author
    $mcolor = imageColorAllocate($img, 255, 0, 0); //Цвет шрифта author

    $size=getimagesize($imgage_path); //Узнаем размер изображения
    $w=(int)$size[0]; // ширина
    $h=(int)$size[1]; // высота
        
    // текст по центру 
        $boxgen = imagettfbbox($font_size, 0, $font, $txt[1]);
        $t = ($h/2) - $lines * (($boxgen[3]-$boxgen[5]) / 2 + 140);
        for ($i = 1; $i <= $lines; $i++) {
                $box = imagettfbbox($font_size, 0, $font, $txt[$i]);
                $x = ($w/2)-($box[2]-$box[0])/2; //по оси x
                #$y = ($h/2)-($box[3]-$box[5])/2; //по оси y
                $y = $t + (($box[3]-$box[5])/2)*$i + 140*$i;
                
                //Обводка 
                imagettftext($img, $font_size, 0, $x+2, $y, $shadow, $font, $txt[$i]);
                imagettftext($img, $font_size, 0, $x, $y+2, $shadow, $font, $txt[$i]);
                //Разметка самого текста
                imagettftext($img, $font_size, 0, $x, $y, $color, $font, $txt[$i]);             
        } // end FOR    


        //Author
    $abox = imagettfbbox($afont_size, 0, $afont, trim($txtparts[1]));
    $ax = ($w/2)-($abox[2]-$abox[0])/2; //по оси x
    $ay = ($h)-($abox[3]-$abox[5])/2; //по оси y        
    imagettftext($img, $afont_size, 0, $ax, $ay, $acolor, $afont, trim($txtparts[1]));

        //Mocah
    $mbox = imagettfbbox($mfont_size, 0, $mfont, trim($txtparts[2]));
    $mx = ($w/2)-($mbox[2]-$mbox[0])/2; //по оси x
    $my = ($h)-($mbox[3]-$mbox[5])/2 - 120; //по оси y  
    imagettftext($img, $mfont_size, 0, $mx, $my, $mcolor, $mfont, trim($txtparts[2]));  
        
        

        } // end IF !emprt
?>

в таком виде не заработало, картинка не создается. Ну, ничего, можно просто потом чистить директорию от картинок что создались.

У этого скрипта есть еще один косяк, в другой области. Иногда он считает неправильно межстрочный интервал (текст по центру) и строки могут незначительно наехать друг на друга.


silicoid

вы зря убрали снизу

        imagejpeg($img, $new_filename);
imagedestroy($img);
        $url="http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
        $url = str_replace("i.php", $new_filename, $url);
        header('Location: '.$url);

это как раз тот кусочек кода, который создает на диске файл

зы.

Для правильной работы любых скриптов, связанных с записей/считыванием данных с диска, надо указывать абсолютный путь к файлу.
что-то вроде $file_path = $_SERVER[‘DOCUMENT_ROOT’]  . ‘/filename.txt ‘;
Иначе в работе скриптов появляется очень много неизвестных.


iccup

да, все так. Теперь все работает.

Да, картинки создаются, но они по-прежнему создаются в директории и там копятся. Я думал суть манипуляций в том, чтобы не копить их там.

Скрипт сейчас  выглядит вот так

<?php 

    $text = $_GET['text']; //Забираем тест
        // split text parts
        $new_filename =  md5($text).".jpg";
if ( file_exists( $new_filename ))
{
        $url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
        $url = str_replace("i.php", $new_filename, $url);
        header('Location: '.$url);
        die(); /* или любой другой способ прервать выполнение функции, если это функция */
}
        $txtparts = explode("|", $text);
        if(!empty(trim($txtparts[0])) && !empty(trim($txtparts[1])) && !empty(trim($txtparts[2])) && !empty(trim($txtparts[3]))){

    $imgage_path = "img/".trim($txtparts[3]); //Путь к изображению

        $words = explode(" ", trim($txtparts[0]));
        if(count($words) > 5){
                $txt[1] = '';
                $txt[2] = '';
                $txt[3] = '';
                $txt[4] = '';
                for ($i = 0; $i < count($words); $i++) {
                        if($i < 4) $txt[1] .= $words[$i]." ";
                        if($i >= 4 && $i < 8) $txt[2] .= $words[$i]." ";
                        if($i >= 14 && $i < 21) $txt[3] .= $words[$i]." ";
                        if($i >= 21 && $i < 29) $txt[4] .= $words[$i]." ";                      
                } // end FOR
                $txt[1] = mb_substr($txt[1], 0, -1);
                $txt[2] = mb_substr($txt[2], 0, -1);
                $txt[3] = mb_substr($txt[3], 0, -1);
                $txt[4] = mb_substr($txt[4], 0, -1);                                            
            $font_size = 182; // размер шрифта
                if(!empty(trim($txt[4]))){$lines = 4;}
                elseif(!empty(trim($txt[3]))){$lines = 3;}              
                elseif(!empty(trim($txt[2]))){$lines = 2;}
                else{$lines = 1;}
        } else {
                $txt[1] = trim($txtparts[0]);
            $font_size = 200; // размер шрифта
                $lines = 1;
        }

    $img = imagecreatefromjpeg($imgage_path); // создаём новое изображение из файла
    $font = "fonts/FREESCPT.TTF"; // путь к шрифту      
    $color = imageColorAllocate($img, 255, 255, 255); //Цвет шрифта
    $shadow = imageColorAllocate($img, 0, 0, 0); // цвет обводки (черный цвет)

        // author font
    $afont = "fonts/NIAGSOL.TTF"; // путь к шрифту author
    $afont_size = 72; // размер шрифта author
    $acolor = imageColorAllocate($img, 255, 255, 255); //Цвет шрифта author

        // mocah font
    $mfont = "fonts/FREESCPT.TTF"; // путь к шрифту author
    $mfont_size = 72; // размер шрифта author
    $mcolor = imageColorAllocate($img, 255, 0, 0); //Цвет шрифта author

    $size=getimagesize($imgage_path); //Узнаем размер изображения
    $w=(int)$size[0]; // ширина
    $h=(int)$size[1]; // высота
        
    // текст по центру
        $boxgen = imagettfbbox($font_size, 0, $font, $txt[1]);
        $t = ($h/2) - $lines * (($boxgen[3]-$boxgen[5]) / 2 + 140);
        for ($i = 1; $i <= $lines; $i++) {
                $box = imagettfbbox($font_size, 0, $font, $txt[$i]);
                $x = ($w/2)-($box[2]-$box[0])/2; //по оси x
                #$y = ($h/2)-($box[3]-$box[5])/2; //по оси y
                $y = $t + (($box[3]-$box[5])/2)*$i + 140*$i;
                
                //Обводка
                imagettftext($img, $font_size, 0, $x+2, $y, $shadow, $font, $txt[$i]);
                imagettftext($img, $font_size, 0, $x, $y+2, $shadow, $font, $txt[$i]);
                //Разметка самого текста
                imagettftext($img, $font_size, 0, $x, $y, $color, $font, $txt[$i]);            
        } // end FOR    


        //Author
    $abox = imagettfbbox($afont_size, 0, $afont, trim($txtparts[1]));
    $ax = ($w/2)-($abox[2]-$abox[0])/2; //по оси x
    $ay = ($h)-($abox[3]-$abox[5])/2; //по оси y        
    imagettftext($img, $afont_size, 0, $ax, $ay, $acolor, $afont, trim($txtparts[1]));

        //Mocah
    $mbox = imagettfbbox($mfont_size, 0, $mfont, trim($txtparts[2]));
    $mx = ($w/2)-($mbox[2]-$mbox[0])/2; //по оси x
    $my = ($h)-($mbox[3]-$mbox[5])/2 - 120; //по оси y  
    imagettftext($img, $mfont_size, 0, $mx, $my, $mcolor, $mfont, trim($txtparts[2]));  
        
        imagejpeg($img, $new_filename);
        imagedestroy($img);
        $url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
        $url = str_replace("i.php", $new_filename, $url);
        header('Location: '.$url);
        } // end IF !emprt
?>


silicoid

они будут копиться так как имя файла, это хэш запроса. то-есть, чем больше разных запросов, тем больше файлов.
если сервер выдержит нагрузку, то можно попробовать сделать так

        header('Content-Type: image/jpeg');
        imagejpeg($img);
        imagedestroy($img);

вместо

        imagejpeg($img, $new_filename);
        imagedestroy($img);
        $url="http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
        $url = str_replace("i.php", $new_filename, $url);
        header('Location: '.$url);

разумеется, сверху надо убрать все проверки иначе они будут просто молотить впустую.

но это опять же большая нагрузка на вычислительные ресурсы.
если картинка маленькая — вопросов нет. если картинка размером от 1600х1200 и больше, то нагрузка на процессор уже будет приличная.


iccup

Это да, нагрузка есть. Буду работать как есть.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *