Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разбиение текста на строки по ширине изображения 
V
    Опции темы
mr.Anderson
Дата 21.9.2010, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 1
Всего: 128



Задача. Есть картинка. Известны, разумеется, ее физические размеры (разрешение). Требуется: переданный в параметре текст (передается он одной строкой) разбить на массив строк так, чтобы каждая из строк целиком убиралась в данное изображение по ширине (а не вылезала за края). Я понимаю, что нужно использовать MeasureString, однако как это правильно сделать - я не знаю. Текущий вариант такой, но он почему-то размещается всего лишь на половине изображения, а половина (правая половина) остается пустой. Шрифт не моноширинный, еще в этом проблема, я меряю лишь один символ, а они имеют разную ширину. Но все равно неверно получается. Весь текст, состоящий из букв, не может быть сильно больше/меньше измеренного символа, умноженного на их количество. А получается чуть ли не вдвое, поэтому я не думаю, что проблема в замере ширины символа. Но в чем именно тогда - не могу понять.

Вот часть функции, которая рисует на изображении переданное сообщение msg заданным шрифтом font. Она все делает правильно, исключая только вышеуказанный факт - размещение текста на левой половине изображения.
Код

public void SetMessage(string msg, Font font)
{
    msg = msg.Trim();
    _message = new Bitmap(_input.Width, _input.Height);
    using (Graphics g = Graphics.FromImage(_message))
    {
        // calculate size of the font and max length of the message
        SizeF size = g.MeasureString("a", font);
        int maxHorizontal = (int) ((_message.Width - 20) / size.Width);
        // split the message by image width with taking attention on the selected font
        string[] text = _Split(msg, maxHorizontal);
    }
    // ...
    g.FillRectangle(new SolidBrush(Color.White), 0, 0, _input.Width, _input.Height);
    for (int i = 0; i < text.Length; i++)
        g.DrawString(text[i], font, new SolidBrush(Color.Black), 5, size.Height*i + 7); // умножение на высоту и прибавка - лишь выравнивание, они особой роли не играют
}

На всякий случай вот функция _Split, разделяющая строчку на отдельные подстроки.
Код

/// <summary>
/// Splits the specified message to paragraphs based on maximum length of a horizontal string.
/// </summary>
/// <param name="message">Message.</param>
/// <param name="maxHorizontal">Maximum length of a horizontal string.</param>
/// <returns></returns>
private static string[] _Split(string message, int maxHorizontal)
{
    List<string> list = new List<string>();
    // we should split the specified message with taking attention on the words (splitting words isn't allowed)
    message = message.Trim();
    while (!String.IsNullOrEmpty(message) && maxHorizontal < message.Length)
    {
        int i = maxHorizontal;
        while (i >= 0)
        {                    
            if (message[i] == ' ')
            {
                list.Add(message.Substring(0, i));
                message = message.Substring(i + 1, message.Length - i - 1);
                break;
            }
            i--;
        }
    }
    if (!String.IsNullOrEmpty(message))
        list.Add(message);
    return list.ToArray();
}



--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
CYBERDREAM
Дата 21.9.2010, 21:45 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


I think, there4 I am
***


Профиль
Группа: Завсегдатай
Сообщений: 1096
Регистрация: 31.10.2006
Где: CyberLand

Репутация: 8
Всего: 28



ну как вариант можно так:
Код

public Form1()
{
    InitializeComponent();

    SetMessage(
        @"Задача. Есть картинка. Известны, разумеется, ее физические размеры (разрешение). Требуется: переданный в параметре текст (передается он одной строкой) разбить на массив строк так, чтобы каждая из строк целиком убиралась в данное изображение по ширине (а не вылезала за края). Я понимаю, что нужно использовать MeasureString, однако как это правильно сделать - я не знаю. Текущий вариант такой, но он почему-то размещается всего лишь на половине изображения, а половина (правая половина) остается пустой. Шрифт не моноширинный, еще в этом проблема, я меряю лишь один символ, а они имеют разную ширину. Но все равно неверно получается. Весь текст, состоящий из букв, не может быть сильно больше/меньше измеренного символа, умноженного на их количество. А получается чуть ли не вдвое, поэтому я не думаю, что проблема в замере ширины символа. Но в чем именно тогда - не могу понять.",
        new Font("Cambria", 28));
}

public void SetMessage(string msg, Font font)
{
    Image copy = new Bitmap(pictureBox1.Image);
    using (Graphics g = Graphics.FromImage(copy))
    {
        g.DrawString(msg, font, new SolidBrush(Color.Red), new RectangleF(new PointF(), copy.Size));
    }

    pictureBox2.Image = copy;
}


Присоединённый файл ( Кол-во скачиваний: 14 )
Присоединённый файл  2.png 317,93 Kb


--------------------
Ищем .Net, Java, Javascript разработчиков, Кипр, Лимассол. (знание английского необязательно)
Telegram, skype: kuchuk.artiom
PM MAIL WWW   Вверх
mr.Anderson
Дата 21.9.2010, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 1
Всего: 128



Нда. Все, как всегда, оказалось в разы проще. Большое спасибо.


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
userdab
Дата 22.9.2010, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 3.9.2010

Репутация: нет
Всего: нет



Еще как вариант можно использовать класс StringFormat (пример). Плюс еще может пригодится тема про кач-во рисуемого текста на изображении.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0568 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.