Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

GD+PHP Вывод текста по кривой

4
08 июня 2007 года
mike
3.7K / / 01.10.2002
Может кто сталкивался с красивым решением ??

Кривая задается в виде полилинии.
92
08 июня 2007 года
Тень Пса
2.2K / / 19.10.2006
держи :) ( это по дуге, по произвольной кривой не нашёл :( если найду, кину сюда)

$str - строчка ессна...
$aStart - угол начала текста
$aEnd - угол пследнего символа
$iRadius - радиус дуги
$bCCW - тру или фолс, по часовой или против

Код:
<?php

function DrawTextArc($str, $aStart, $aEnd, $iRadius, $bCCW)
{
        $nFont = 5;
         
        // create image to store each character
        $xFont = imagefontwidth($nFont);
        $yFont = imagefontheight($nFont);
        $imgChar = imagecreatetruecolor($xFont, $yFont);
        // create overall image
        $iCentre = $iRadius + max($xFont, $yFont);
        $img = imagecreatetruecolor(2 * $iCentre, 2 * $iCentre);
        // sort out colours
        $colBG = imagecolorallocate($img, 255, 255, 255);
        $colBGchar = imagecolorallocate($imgChar, 255, 255, 255);
        $colFGchar = imagecolorallocate($imgChar, 0, 0, 0);
        imagefilledrectangle($img, 0, 0, 2 * $iCentre, 2 * $iCentre, $colBG);
         
        // arrange angles depending on direction of rotation
        if ($bCCW)
        {
                while ($aEnd < $aStart)
                {
                        $aEnd += 360;
                }
        }
        else
        {
                while ($aEnd > $aStart)
                {
                        $aEnd -= 360;
                }
        }
         
        $len = strlen($str);

        // draw each character individually
        for ($i = 0; $i < $len; $i++)
        {
                // calculate angle along arc
                $a = ($aStart * ($len - 1 - $i) + $aEnd * $i) / ($len - 1);
         
                // draw individual character
                imagefilledrectangle($imgChar, 0, 0, $xFont, $yFont, $colBGchar);
                imagestring($imgChar, $nFont, 0, 0, $str[$i], $colFGchar);
         
                // rotate character
                $imgTemp = imagerotate($imgChar, (int)$a + 90 * ($bCCW ? 1 : -1), $colBGchar);
                $xTemp = imagesx($imgTemp);
                $yTemp = imagesy($imgTemp);
         
                // copy to main image
                imagecopy($img, $imgTemp,
                                        $iCentre + $iRadius * cos(deg2rad($a)) - ($xTemp / 2),
                                        $iCentre - $iRadius * sin(deg2rad($a)) - ($yTemp / 2),
                                        0, 0, $xTemp, $yTemp);
        }
         
        return $img;
}



$img = DrawTextArc("This is the string to display", 135, 300, 200, TRUE);

// output the image
header("Content-type: image/jpeg");
imagejpeg($img);

?>
4
14 июня 2007 года
mike
3.7K / / 01.10.2002
Это десткий лепет. Нужно вывести красиво и по произвольной кривой, как Google Maps выводит названия улиц:

http://maps.google.com/?ie=UTF8&ll=59.966611,30.500278&spn=0.03978,0.1157&z=13&om=1
92
14 июня 2007 года
Тень Пса
2.2K / / 19.10.2006
я не уверен что гугл это делает средствами php. везде где назодил подобный вопрос, видел ответ "математические вычисления вам помогут".

ну вот и.... собссна считай :)

но есть еще вариант: использовать SVG
12
15 июня 2007 года
alekciy
3.0K / / 13.12.2005
А почему бы не использовать для не совсем простой задачи более мощные средства чем GD? Например ImageMagick (есть хосты которые его поддерживают да и с нормальным хостером думаю не будет проблем договориться об установке). В частности под пых:
http://www.magickwand.org/
по сабжу:
http://www.magickwand.org/DrawAnnotation.html
http://www.magickwand.org/DrawPolyline.html
http://www.magickwand.org/DrawBezier.html
12
15 июня 2007 года
alekciy
3.0K / / 13.12.2005
Цитата: Тень Пса

но есть еще вариант: использовать SVG


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

4
15 июня 2007 года
mike
3.7K / / 01.10.2002
1. SVG отметается.
2. Мне все равно чем рисовать, GD, ImageMagick, Dlephi, MSVC. Все равно
3. Есть трудность в реализации. Не получается узнать правильные размеры TTF символов написанных под углом.
92
15 июня 2007 года
Тень Пса
2.2K / / 19.10.2006
хорошо, как доберусь до дома. а это будет не раньше, чем завтра - попробую. опять же ЕСЛИ получится - поделюсь :)

[quote=alekciy]
Безусловно мощная вещь. Однако учитывая уровень поддежки в браузерах для широкой публике об этом формате придется задуматься этак через 2-4 года, не раньше...
[/quote]

жаль... а вещь на самом деле мощная :)

ЗЫ: FF нормально рисует :)
12
15 июня 2007 года
alekciy
3.0K / / 13.12.2005
Цитата: Тень Пса

ЗЫ: FF нормально рисует :)


Опера тоже неплохо. Но пока осел будет иметь ~80% рынка и не будет поддерживать SVG нативно для широкого использования SVG можно забыть. Как что, как это обычно бывает ждем отстающий MS :D , он как всегда выступает тормозом прогресса несомого от W3C.

12
16 июня 2007 года
alekciy
3.0K / / 13.12.2005
Порылся в ImageMagick.... как ни жаль, но я ошибся, готового решения рисования текста по полилинии там нет. И вообще в рунете (да и инглишнете) что-то не удалось найти готового путевого решения под веб.
12
16 июня 2007 года
alekciy
3.0K / / 13.12.2005
Цитата: mike
Это десткий лепет.


Не обязательно. Если вдуматься:
http://alekciy.ru/bufer/pic.png
http://alekciy.ru/bufer/pic2.png

:D
то задача сводиться к геометрии школьного курса с использованием теоремы Пифагора. И вывод произвольного текста по ломанной кривой состоящей из отрезков можно реализовать даже срествами GD либы.

12
17 июня 2007 года
alekciy
3.0K / / 13.12.2005
Что-то прямо крупно заинтерисовала меня задача по сабжу... геометрией что ли давно не занимался. Спокойно я от неё видимо не устранюсь.

Ха... пересмотрел свои каракули и понял, что забыл учесть то, что для картинок букв начало координат лежит сверху-слева. Сейчас кое что почертил на бумаге еще и в принципе алгоритм рисования текста по ломанной готовой. Скелетик даже в GD испытал, рисует как и требуется. Пожалуй даже могу код привести в порядок и выложить кому нужно....
12
17 июня 2007 года
alekciy
3.0K / / 13.12.2005
Mike что-то как народ безмолвствует :D .
В общем вот что я наропал:
http://alekciy.ru/test/textToPolyline.php

Для тех, кто хочеть задать другой путь вывода линий можно задать через GET в переменную arr. При этом это должен быть двухмерный сериализованный массив.

Например: http://alekciy.ru/test/textToPolyline.php?arr=a:4:{i:0;a:2:{i:0;i:0;i:1;i:0;}i:1;a:2:{i:0;i:100;i:1;i:120;}i:2;a:2:{i:0;i:200;i:1;i:130;}i:3;a:2:{i:0;i:500;i:1;i:180;}}
или
http://alekciy.ru/test/textToPolyline.php?arr=a:4:{i:0;a:2:{i:0;i:0;i:1;i:100;}i:1;a:2:{i:0;i:100;i:1;i:120;}i:2;a:2:{i:0;i:200;i:1;i:130;}i:3;a:2:{i:0;i:500;i:1;i:180;}}
Линия под надпись выводиться для наглядности.

Для тех кто забыл что есть двухмерный массив и сериализация:
 
Код:
$arr = Array (
    Array(0,100),
    Array(100,120),
    Array(200,130),
    Array(500,180)
);
echo serialize($arr);
92
17 июня 2007 года
Тень Пса
2.2K / / 19.10.2006
alekciy, ... слофф нет :) выкладывай!

PS: а я тока домой пришёл :D
12
18 июня 2007 года
alekciy
3.0K / / 13.12.2005
Цитата: Тень Пса
alekciy, ... слофф нет :) выкладывай!

PS: а я тока домой пришёл :D


Исходники? Легко? Только помним гыпыэль и все такое прочее. В общем если сгодиться не забудем автора :D

Код:
<?php

class ImageText
{
    public $text;
    public $image;
    public $view_line = false;

    public function toPolyline($coordinates)
    {
        $coordinates = unserialize($coordinates);

        $nFont = 5;
        $x = 500;
        $y = 500;

        $xFont = imagefontwidth($nFont);
        $yFont = imagefontheight($nFont);
        $imgChar = imagecreatetruecolor($xFont, $yFont);
        $img = imagecreatetruecolor($x,$y);

        $colBG = imagecolorallocate($img, 255, 255, 255);
        $colBGchar = imagecolorallocate($imgChar, 255, 255, 255);
        $colFGchar = imagecolorallocate($imgChar, 0, 0, 0);

        imagefilledrectangle($img, 0, 0, $x, $y, $colBG);

        $length = count($coordinates);
        $length--;
        for ($i = 0; $i < $length; $i++)
        {
            $X1 = $coordinates[$i][0];
            $Y1 = $coordinates[$i][1];

            $X2 = $coordinates[$i+1][0];
            $Y2 = $coordinates[$i+1][1];

            $length_segment = floor(sqrt(abs($X1 - $X2) * abs($X1 - $X2) + abs($Y1 - $Y2) * abs($Y1 - $Y2)));

            $count_char = $length_segment / $xFont;
            if ($count_char < 1)
            {
                continue;
            }
            else
            {
                $count_char = floor($count_char);
            };

            $imgChar = imagecreatetruecolor($xFont*$count_char, $yFont);

            $alfaRad = atan(abs(($Y1 - $Y2)/($X1 - $X2)));
            if ($Y1 > $Y2)
            {
                $alfaRad = - $alfaRad;
            };
            $alfaDeg = rad2deg($alfaRad);

            if ($this->text == '') {break;};
            $sub_text = substr($this->text,0,$count_char);
            $this->text = substr_replace($this->text,'',0,$count_char);

            imagefilledrectangle($imgChar, 0, 0, $xFont*$count_char, $yFont, $colBGchar);
            imagestring($imgChar, $nFont, 0, 0, $sub_text, $colFGchar);

            $imgTemp = imagerotate($imgChar,-$alfaDeg,$colBGchar);
            $xTemp = imagesx($imgTemp);
            $yTemp = imagesy($imgTemp);

            $xBase = $X1 + cos($alfaRad) * $xFont;
            $yBase = $Y1 + sin($alfaRad) * $xFont;

            $Xn = $xBase;
            $Yn = $yBase - cos($alfaRad)*$yFont;

            imagecopy($img, $imgTemp,$Xn,$Yn,0,0,$xTemp, $yTemp);

            if ($this->view_line)
            {
                imageline($img,$X1,$Y1,$X2,$Y2,$colFGchar);
            };
        };
        $this->image = $img;
        return true;
    }
};

$img = new ImageText();
$arr = Array (
    Array(0,100),
    Array(100,120),
    Array(200,130),
    Array(500,180)
);

$arr = 'a:4:{i:0;a:2:{i:0;i:0;i:1;i:100;}i:1;a:2:{i:0;i:100;i:1;i:120;}i:2;a:2:{i:0;i:200;i:1;i:130;}i:3;a:2:{i:0;i:500;i:1;i:180;}}';
if (isset($_GET['arr']))
{
    $arr = $_GET['arr'];
};

$img->text = 'Text to polyline. Text to polyline. Text to polyline. Text to polyline.';
$img->view_line = true;
$img -> toPolyline($arr);

header("Content-type: image/jpeg");
imagejpeg($img->image);
?>


Кстати как рисует GD либа векторные изображения мне не понравилось. Очень большие подозрения, что с помощью того же ImageMagik можно будет добиться более красивых результатов.
92
18 июня 2007 года
Тень Пса
2.2K / / 19.10.2006
если буду использовать, то вот так:
 
Код:
/**
 * @author Alekciy
 */


добавлю :) обещаю!
12
20 июня 2007 года
alekciy
3.0K / / 13.12.2005
:D ))
А mike-у видно способ не понравился, или что интереснее нашел. Хотя как поиск не пытал так ни чего путного не выудил.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог