Окт 12

Недавно Владимир в комментариях к заметке о SPAW задал вопрос относительно вставки уменьшенных копий изображения.

В свое время передо мной тоже стояла такая задача. Здесь я расскажу о том, как я решил ее в своем проекте.

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

В последнем проекте (новостной сайт) была необходимость создания превьюшек, а также максимально легко добавлять к изображениям подпись и источник, откуда оно было взято. Подпись редакторы указывали в атрибуте alt, источник – в title, а необходимые размеры брались из style. Кроме того, использовался и атрибут align.

Ниже приведен код метода из контроллера действий News (проект написан на Zend Framework), который отвечал за необходимый мне функционал. Код снабжен большим количеством комментариев, поэтому отдельно я его описывать не стану. Если возникнут вопросы – задавайте их в комментариях.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
 * Нахождение и обработка изображений
 *
 * @param string text HTML-код для обработки
 * @return string HTML-код после обработки
 */

protected function _parseImages($text)
{
    // Массив для хранения всех найденных в тексте изображений
    $imagesInInputText = array();
    // Собственно поиск... Обратите внимание на флаг U - я использую юникод
    preg_match_all("#<img (.*)/>#Uim",$text,$imagesInInputText);
    // Инициализируем массив для временного хранения найденных данных
    $matches = array();
    // Перебираем массив найденных изображений
    foreach ($imagesInInputText[0] as $imageTag) {
        // Инициализируем массив для хранения данных по разбираемому изображению
        $currentImage = array();
        // Определяем путь к изображению
        preg_match("#src=\"(.+)\"#Ui",$imageTag,$matches);
        $currentImage['src'] = $matches[1];
        // Находим аттрибуты style, alt, title и align
        preg_match("#style=\"(.+)\"#Ui",$imageTag,$matches);
        $currentImage['style'] = $matches[1];
        preg_match("#alt=\"(.*)\"#Ui",$imageTag,$matches);
        $currentImage['alt'] = $matches[1];
        preg_match("#title=\"(.*)\"#Ui",$imageTag,$matches);
        $currentImage['title'] = $matches[1];
        preg_match("#align=\"(.*)\"#Ui",$imageTag,$matches);
        $currentImage['align'] = $matches[1];
        // если найден атрибут style, пытаемся определить требуемую ширину и высоту
        if (strlen($currentImage['style']) > 0) {
            preg_match("#WIDTH:[ ]{0,}([0-9]{0,})px#Ui",$imageTag,$matches);
            $currentImage['width'] = $matches[1];
            preg_match("#HEIGHT:[ ]{0,}([0-9]{0,})px#Ui",$imageTag,$matches);
            $currentImage['height'] = $matches[1];
        }

        // Получаем информацию о размерах оригинального изображения.
        $filename = $_SERVER['DOCUMENT_ROOT'] . $currentImage['src'];
        $imagesize = @getimagesize($filename);
        // Если ширина и высота для текущего изображения не были заданы,
        // значит вставлять будем оригинал, поэтому в качестве ширины и высоты,
        // берем соответствующие значения оригинала
        if ($currentImage['width'] == NULL) {
            $currentImage['width'] = $imagesize[0];
        }
        if ($currentImage['height'] == NULL) {
            $currentImage['height'] = $imagesize[1];
        }

        // Если ширина или высота требуемого изображения отличаются от оригинала,
        // изменим исходный тег изображения: перепишем атрибут src.
        // В этот примере новое значение устанавливается так: перед путем к сохраненному
        // оригинальному файлу добавляется строка "/thrumbs". Затем следует путь к файлу
        // изображения до расширения, строка _w{$currentImage['width']}_h{$currentImage['height']},
        // которая содержит требуемые значения ширины и высоты, за которой следует расширение.
        //
        // Например нужна превьшка 150х200 пикселей:
        // Было - /gallery/politics/Yushenko.jpg
        // Стало - /thrumbs/gallery/politics/Yushenko_w150_h200.jpg
        // При запросе данного файла будет вызван контроллер Thrumbs, который
        // сгенерирует превью необходимого размера и сохранит его в физическую
        // папку /thrumbs/, чтобы при последующих запросах файл отдавался статически
        if ($currentImage['width'] != $imagesize[0] or $currentImage['height'] != $imagesize[1]) {
            $dotPosition = strrpos($currentImage['src'], '.');
            $currentImage['newSrc'] = '/thrumbs' . substr($currentImage['src'],0,$dotPosition)
                                    . "_w{$currentImage['width']}_h{$currentImage['height']}"
                                    . substr($currentImage['src'],$dotPosition);
            $newImageTag = preg_replace("#{$currentImage['src']}#",$currentImage['newSrc'],$imageTag);
        } else {
            $newImageTag = $imageTag;
        }
       
        // Генерируем код для текущего изображения.
        // Более правильно использовать шаблон, но у меня до этого руки не дошли
        $output = '<div class="image';
        if ($currentImage['align'] != NULL) $output .= ' ' . $currentImage['align'];
        $output .= "\">\n    {$newImageTag}\n";
        if ($currentImage['alt'] != NULL) $output .= '    <div class="alt">' . $currentImage['alt'] . "</div>\n";
        if ($currentImage['title'] != NULL) $output .= '    <div class="title">' . $currentImage['title'] . "</div>\n";
        $output .='</div>';
        // Заменяем оригинальный тег изображения на сгенерированный вывод
        $text = preg_replace("#{$imageTag}#",$output,$text);
    }        
    // возвращаем измененный текст
    return $text;
}

Стоит отметить, что приведенный пример писался под конкретную задачу. В вашем случае он может потребовать значительной переработки. Я же ставил себе цель – показать саму идею вставки превью изображений в редакторе SPAW.

Share

Автор: Кирилл Павлюков \\ Метки: , , ,


2 коммент. к “Как вставить уменьшенную копию изображения в редакторе SPAW”

  1. 1. sergey пишет:

    Вопрос насчет строки…
    preg_match_all(«##Uim»,$text,$imagesInInputText);
    дело в том что данный поиск работает некоректно если в строке идет несколько изображений. и пропадает смысл цикла.поэтому необходимо использовать
    preg_match_all(«//i»,$text,$imagesInInputText);
    А так огромное спасибо за скрипт – очень помог и уменьшил головную боль.

  2. 2. sergey пишет:

    ггг не отобразился рег поиск. там вот это перед имаже можно добавить пробелов кстате.

Оставьте комментарий или два