Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Вставка изображений в нужных местах текста
 
 автор: Sarat   (08.10.2014 в 19:48)   письмо автору
 
 

Здравствуйте! Делаю простую панель управления сайтом. Сайт с использованием mysql. Нужно редактировать страницу, состоящую из Заголовка и Текста.
В панели выводится форма, из базы вытаскиваю содержание заголовка, вставляю в форму, в поле заголовка, текст вставляется в соответствующее поле.
Необходимо чтобы администратор сайта мог вставить в любое место текста два, три изображения.
Подскажите пожалуйста как это сделать? В какую сторону склоняться?
Хочется самым простым способом. НЕ нужно сложных решений! Я кодер и только учусь! Хотелось бы обойтись без явы. Может какие то метки ставить, а при занесении в базу текста, вместо меток подставлять адреса с картинками. Картинки будут обрабатываться скриптом и сохраняться в определенной директории под определенным именем.

  Ответить  
 
 автор: Denandi   (08.10.2014 в 21:52)   письмо автору
 
   для: Sarat   (08.10.2014 в 19:48)
 

Насколько я понял.. вам нужно просто установить редактор текста. Они многие используются с файловым менеджером. Т.е. в любом тексте вы можете интегрировать любое количество изображений, с их заполнением альт, тайтл, js и прочее.

  Ответить  
 
 автор: Denandi   (08.10.2014 в 21:54)   письмо автору
 
   для: Sarat   (08.10.2014 в 19:48)
 

для примера http://ckeditor.com/demo

  Ответить  
 
 автор: Sarat   (10.10.2014 в 09:33)   письмо автору
 
   для: Denandi   (08.10.2014 в 21:54)
 

Спасибо за идею. Я понял, нужно чтобы редактор встраивался в поле моей формы.
А есть что то простое, прям минимализм? Чтоб перенос абзаца, выделение жирным и вставка фото в любое место к примеру. И администратор не будет лишний раз думать и выбиться из стиля сайта не получиться.
Кроме того в этих редакторах предлагаются на выбор шрифты, используемые в системе, а это совсем лишнее и не правильно, т.к. у других пользователей может не быть этих шрифтов и они увидят свой Ариал. Мне нужно на выбор 2 шрифта, которые определяются в css через @font-face и загружаются с сайтом. Например мне не нужно чтобы был выбор размера шрифта. Как убрать всё лишнее?

  Ответить  
 
 автор: Igorek   (10.10.2014 в 12:29)   письмо автору
 
   для: Sarat   (10.10.2014 в 09:33)
 

Тулбар настраивается
http://ckeditor.com/demo#toolbar

  Ответить  
 
 автор: confirm   (10.10.2014 в 12:45)   письмо автору
 
   для: Sarat   (10.10.2014 в 09:33)
 

Есть и прям минимализм, в сети же можно поискать:

http://akzhan.github.io/jwysiwyg/
http://cheeaun.github.io/mooeditable/

А еще меньший минимализм, это

<div style="width:500px;height:400px;border:1px solid #777" contenteditable="true"></div>

Это и есть основа всех этих редакторов, несложно добавить только свой минимализм, ну для этого надо обладать знаниями.

  Ответить  
 
 автор: Igorek   (10.10.2014 в 12:59)   письмо автору
 
   для: Sarat   (10.10.2014 в 09:33)
 

Тогда уж в догонку
Список WYSIWYG редакторов: http://habrahabr.ru/post/129262/
А вот этот из минималистичных на мой взгляд весьма симпатичный: http://imperavi.com/redactor/

  Ответить  
 
 автор: confirm   (10.10.2014 в 13:49)   письмо автору
 
   для: Igorek   (10.10.2014 в 12:59)
 

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

  Ответить  
 
 автор: rurgil   (08.10.2014 в 22:09)   письмо автору
 
   для: Sarat   (08.10.2014 в 19:48)
 

В таблицу добавить новое поле
и организовать загрузку файлов с сервера

  Ответить  
 
 автор: confirm   (09.10.2014 в 01:40)   письмо автору
 
   для: Sarat   (08.10.2014 в 19:48)
 

Даже с минимумом комфорта без JS этого не сделать. Если "абы", то вставляйте в текст в место будущей картинки что-то условное, например, :0:, :1: и т.д., где номер соответствует индексу полей file. По получению формы и удачной загрузке изображения, заменяйте эти условности тегом img с параметрами загруженного изображения соответствующего поля file.

  Ответить  
 
 автор: Sarat   (10.10.2014 в 09:27)   письмо автору
 
   для: Sarat   (08.10.2014 в 19:48)
 

Честно говоря пока не понимаю как это всё будет работать.
Может быть действительно взять готовый скрипт и внедрить его?
Нужно чтобы в поле формы определялись абзацы и места будущих изображений (пусть их будет до трех). А ниже будет еще три поля для выбора и загрузки этих изображений. Затем при нажатии кнопки "Редактировать" форма с 1- заголовком, 2- текстом и метками будущих фотографий, 3- массив файлов фотографиий отправляется обработчику.
Какой сценарий будет происходить в обработчике мне пока трудно представить (у соседа перфоратор весь мозг вынес), но обработчик фотографий есть уже в виде готовой функции.
На счет редактора текста, пока остановился на http://nicedit.com/demos.php посмотрю что получиться.

  Ответить  
 
 автор: Sarat   (10.10.2014 в 15:06)   письмо автору
 
   для: Sarat   (10.10.2014 в 09:27)
 

Всё-таки я не понимаю, как связать редактор текста с моими изображениями после обработки последних?
Т.е. будущему администратору сначала нужно загрузить несколько картинок, потом на втором шаге редактировать текст с помощью нашего редактора и как то через редактор выбирать готовые фотографии (чесно говоря редактор тут вообще не помогает) . Либо загружать через редактор на посторонний ресурс (такая функция есть в моем редакторе и это вообще не понять как плохо).
Скажите, как умные люди в таком случае делают? Я имею ввиду разработчиков.
p.s. Теперь я понимаю что действительно необходимо отдельное поле в базе для фотографии.

  Ответить  
 
 автор: confirm   (10.10.2014 в 15:38)   письмо автору
 
   для: Sarat   (10.10.2014 в 15:06)
 

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

В силу специфики приложения, когда часть его находится на "бесправном клиенте", а другая часть на сервере, визуальные редакторы для работы с изображением вставленным в текст сначала его загружают на север, а атрибуту src изображения вставленного возвращается ссылка на загруженное.

Это такая кухня ввиду того, что в расчет берется весь зоопарк браузеров. Но, я ведь вам говорил, что администратора можно насильно приковать к любому из браузеров и поддерживающем HTML5. В этом случае поддерживаемый ими FileReader API позволит вставить изображение в текст без предварительной загрузки на север, а его атрибут src будет содержать тело изображения в data:base64. Поле ввода, которым выбирается изображение скрыто. Если изображение удаляется, значит удаляется и поле ввода его. Имя поля file и имя изображения (атрибут который ему присваивается при вставке) имеют один и тот же идентификатор.

Небольшой примочкой можно изменять размеры вставленного изображения, записывая их в стили тега img, у которого src является data:base64.

При отправке формы атрибут src изображения очищается. На сервере при получении формы парсером проверяются изображения в тексте, и если они имеют атрибут name, значит получают из его атрибутов стиля размеры установленные на севере, по которым изображение загруженное полем связанное с тегом изображения уменьшают, и в случае успеха сформированное имя его записывается в атрибут src. В противном случае, при ошибке, вставленный тег изображения удаляется.

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

  Ответить  
 
 автор: Sarat   (10.10.2014 в 18:31)   письмо автору
 
   для: confirm   (10.10.2014 в 15:38)
 

Ну а что готовое, как это назвать? Дадите ссылку, название, хоть какую ещё зацепку?

  Ответить  
 
 автор: confirm   (11.10.2014 в 14:11)   письмо автору
 
   для: Sarat   (10.10.2014 в 18:31)
 

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

А что касается примеров работы с File API в HTML5 такого в сети полно, сами найдете. Но чтобы эти примеры да во что-то, нужны ведь знания JS, а у вас их... Да и вообще нужно понимание того, что нужно, с чем у вас тоже пока...

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

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

И так, с помощью FileReader можно поступить тремя способами:

Вариант 1

Как я писал ранее, вставленному в редактор тегу изображения в качестве src вставляется данные самого изображения кодировнные в Base64. Эти же данные и отправляются на север, то есть самого поля file для этого не требуется - изображение передается как часть текста.

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

<?php
$htm 
'<p>Text text text text text text text text text text text</p><p>Text text text text text text text text text text text</p>';

if(
$_POST) {
    
//сохраняем html, включая вставленные в него изображения
    
$htm preg_replace_callback('/<img[^>]+>/ui', function($v) {
        
preg_match_all('/(src|style|alt)=("[^"]*")/ui'$v[0], $attr);
        
$attr array_combine($attr[1], $attr[2]);
        
//если есть новые вставленные
        
if(preg_match_all('/(?:data\:image\/([jpeg|png|gif]+);base64,([\S]+))/i'$attr['src'], $dataPREG_SET_ORDER)) {
            
preg_match_all('/(width|height):\s+(\d+)/i'$attr['style'], $size); 
            
$size array_combine($size[1], $size[2]); //заданный в редакторе размер
            
if($src imagecreatefromstring(base64_decode($data[0][2]))) {
                
$type $data[0][1];
                
$name time().'.'.$type;
                
$sW imagesx($src);
                
$sH imagesy($src);
                
$dW $size['width'];
                
$dH $size['height'];
                
                
$dst imagecreatetruecolor($dW$dH);
                
imagecopyresampled($dst$src0000$dW$dH$sW$sH);
                
                switch(
$type) {
                    case 
'png' imagepng($dst$name9);
                                 break;
                   case 
'jpeg' imagejpeg($dst$name);
                                 break;
                    case 
'gif' imagegif($dst$name);
                }
                
                
imagedestroy($src);
                
imagedestroy($dst);
                
                return 
'<img style='.$attr['style'].' src="'.$name.'" />';
            }
        } else return 
'<img style='.$attr['style'].' src='.$attr['src'].' />'//ранее вставленное изображение
    
}, $_POST['htm']);
}

?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
.editorbox {
    width: 832px;
}

.editor {
    height: 500px;
    padding: 5px;
    border:1px solid #ddd;
    overflow-y: auto;
}

.toolbar {
    list-style: none;
    margin: 0;
    padding: 2px;
    border-bottom: 2px solid #aaa;
}

.toolbar li {
    display: inline-block;
    padding: 2px 5px;
    border: 1px solid #ddd;
    background: #eee;
    cursor: pointer;
}

#file_editor {
    width: 300px;
    height: 30px;
    padding: 10px;
    position: fixed;
    top: 50%;
    left: 50%;
    margin-left: -160px;
    margin-top: -20px;
    border: 1px solid #777;
    background: #fff;
    box-shadow: 0px 5px 20px #000;
}

textarea, form [type=file] {
    display: none;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
$(function() {
    var reader = new FileReader(); //объект для работы с файлами
    //загружаем текст в редактор
    $('div.editor').html($('textarea').val());
    
    $('ul.toolbar').on('click', 'li', function() {
        //открываем поле file для выбора файла 
        $('<div id=file_editor><input type=file accept="image/jpeg,image/png,image/gif" /></div>').appendTo('body')
            .find('input:file')
            .change(function() {
                //файл выбран
                var f = $(this).parent(); //запомнить панель поля file 
                reader.onload = (function(e) {
                    //чтение файла и добавление его содержимого src изображения
                    $('<img src="' + e.target.result + '" />').load(function() {
                        //проверка на максимально допустимый размер изображения,
                        //если это требуется, например, чтобы оно не приводило 
                        //к горизонтальной прокрутке страницы
                        //или элемента на странице в которую изображение помещено
                        //в примере ширина редактора установлена на ширину такого элемента страницы, равную 800px 
                        var w = this.width > 800 ? 800 : this.width,
                            h = this.width > 800 ? Math.round(800/this.width*this.height) : this.height;
                            //записываем размеры изображения в его стили 
                            $(this).width(w).height(h);
                    }).insertAfter($('div.editor').find('p').first()); //добавляем изображение в редактор
                    //удаляем панель поля file
                    f.remove();                    
                });
                //первый файл из массива выбранного в base64 на чтение 
                reader.readAsDataURL(this.files[0]);
            });
    });
    
    $('form').submit(function() {
        //текст редактора в форму         
        $(this).find('textarea').val($('div.editor').html());
    });
});
</script>    
</head>

<body>
<div class="editorbox">
    <ul class="toolbar"><li>Insert Image</li></ul>
    <div class="editor" contenteditable="true"></div>
</div>

<form method="post">
    <textarea name="htm"><?=$htm?></textarea>
    <button>Send</button>
</form>
</body>
</html>


Пни вставке небольшого числа фото такой вариант вполне приемлем, но если фото много и больших размеров, то нет. Строка Base64, это в три раза больший объем данных, чем бинарные данные изображения, что может перекрывать в итоге максимальный объем данных передаваемых методом POST. Кроме этого, при большом количестве фото и строка для разбора внушительная будет, загружать такую и парсить, это проблема.

Вариант 2

Все также как и в варианте 1, только на сервер передаются данные уже уменьшенного до нужных размеров изображения. То есть их src это Base64 не всего изображения, а малой копии. Сделать это можно с помощью объекта Canvas. В этом случае на сервер будет передаваться гораздо меньший объем данных.

Но на текущий момент Canvas имеет один существенный минус, который возможно в будущем будут устранен. А именно - изображения уменьшенные в canvas страдают зазубренностями на участках резких переходов яркости. То есть, если линия бедра Данаи соприкасающаяся с постелью останется грациозной, то линия другого, освещенного бедра будет собрана из Лего.

Вариант 3

Также как и в варианте 1, при вставке изображения его src будет равно Base64, но только лишь для того, чтобы иметь возможность в редакторе установить ему размер, переместить его, видеть как обтекает его текст и т.д. Отправлять же изображение на сервер будет поле file, которым оно выбиралось на клиенте. Это поле не удаляется после выбора, а добавляется в форму как скрытое, а его имя связывается с атрибутом name изображения, который добавляется тегу img вставленного изображения. Это поле удаляется, если удаляется и его вставленное изображение.

При отправке формы у вставленных изображений атрибут src либо очищается, либо удаляется совсем. На стороне сервера условием добавленного изображения будет являться наличие у тега img атрибута name. В этом случае по значению этого атрибута обрабатывается изображение соответствующего поля file, и результат как src устанавливается тегу img, а атрибут name удаляется.

Связывать лучше по номеру - для атрибута name, это номер, а для поля file, это будет индекс. При чем нумерацию изображений документа нужно отслеживать, то есть в базе хранится не просто сам html-текст документа, но и последний номер изображения использованный в нем. Этот номер при редактировании документа передается на клиент - сценарий вставки изображения в документ будет именовать новые изображения/поля формы начиная с этого номера.

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

То есть, "валить" все загрузки в кучу, именовать их "авось повезет", как это у вас на практике, само по себе плохо, а в случае "связать А с Б" вообще недопустимо.

Все определяется задачей, и если она требует "подождать", значит надо ждать, но если не обязательно, то следующий номер который получится автоинкрементом для записи в базе можно и знать:

<?
$num 
mysql_fetch_object(mysql_query('SHOW TABLE STATUS WHERE name = "table_name"'));
echo 
$num->auto_increment;


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

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования