Программирование >>  Вывод графики 

1 ... 8 9 10 [ 11 ] 12 13 14 ... 19


Вопросы манипулирования изображениями

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

Наиболее важный для понимания момент насчет изображений - они всегда прямоугольны. Это не просто соглашение, это следствие лежащей в основе технологии. Все современные графические карты так устроены, что могут эффективно копировать блоки пикселей из одной области памяти в другую, только если эти блоки пикселей описывают прямоугольную область. Эта ускоренная аппаратно операция может виртуально выглядеть как атомарная, а потому выполняться чрезвычайно быстро. На самом деле, это - ключ к современной высокопроизводительной графике. Эта операция называется передачей битового блока (bitmap block transfer, или BitBlt).

Метод Graphics.DrawImageUnscaled() внутри использует BitBlt, что позволяет нам видеть огромные изображения, содержащие, возможно, миллионы пикселей, которые появляются почти мгновенно. Если бы компьютеру приходилось копировать изображение на экран пиксель за пикселем, то мы бы увидели, как он появляется постепенно, в течение периода длительностью до нескольких секунд.

BitBlt - чрезвычайно эффективная операция, а потому почти все, что связано с отображением картинок и манипулировании ими, выполняется с ее помощью. Даже программное редактирование графических изображений, предусматривающее манипулирование их частями, осуществляется с помощью операции BitBlt между контекстами устройств, представленными областями памяти. Во времена GDI функция Windows API BitBlt() была, наверно, самой важной и наиболее широко используемой функцией для манипуляции изображениями, хотя в GDI+ операция BitBlt в большой степени скрыта в объектной модели GDI+.

Невозможно выполнить операцию BitBlt над непрямоугольными областями, хотя этот эффект можно легко эмулировать. Один из способов является пометка определенного цвета как прозрачного для BitBlt, так что области, окрашенные этим цветом, не перекроют существующие пиксели на целевом устройстве. Можно также указать, что в процессе выполнения BitBlt каждый пиксель результирующего изображения должен быть сформирован в результате некоторой логической операции (такой как битовое И ) над цветами пикселей исходного и целевого изображений. Такие операции поддерживаются аппаратными акселераторами и могут быть использованы для получения разнообразных тонких эффектов. Отметим также, что в объекте Graphics также реализован и другой метод - DrawImage(). Он подобен DrawImageUnscaled(), но представлен большим количеством перегрузок, которые позволяют специфицировать более сложные формы BitBlt, используемые в процессе отображения. DrawImage() также позволяет рисовать (с помощью BitBlt) только определенную часть изображения либо выполнять некоторые операции, такие как масштабирование (увеличивая или уменьшая размер).

Рисование текста

Раскрытие очень важной темы отображения текста в этой главе было отложено вплоть до настоящего момента, поскольку рисование текста на экране (в общем случае) более сложно, чем рисование простой графики. Хотя чрезвычайно легко вывести одну или две строки текста, не особенно заботясь об их внешнем виде - для этого нужен один простой вызов метода Graphics.DrawString() - но если вы попытаетесь отобразить документ, который включает в себя значительный объем текста, то быстро обнаружите, что все существенно усложнится. На то есть две причины.



□ Если вы хотите, чтобы текст выглядел привлекательно, вам следует разобраться с концепцией шрифтов. В то время как для рисования фигур необходимы кисти и перья в качестве вспомогательных объектов, процесс рисования текста требует в качестве вспомогательных объектов применять шрифты. И понимание шрифтов - непростая задача.

□ Текст должен быть размещен в окне очень тщательно. Обычно пользователи ожидают, что слова будут следовать одно за другим, и четко выровнены. Обеспечить это сложнее, чем может показаться на первый взгляд. Для начала, скажем, что обычно вы не можете предвидеть, сколько места на экране должно занять то или иное слово. Это нужно вычислять (используя метод Graphics.MeasureString()). К тому же пространство, занятое словом на экране, зависит от его относительного положения в документе. Если ваше приложение должно выполнять перенос строк, то вам придется особенно тщательно рассчитывать размеры слов, чтобы принять решение, где следует поместить перенос строки. Когда вы в следующий раз запустите Microsoft Word, обратите внимание на то, как Word постоянно переупорядочивает текст по мере его ввода: ему приходится выполнять огромный объем сложной обработки. Конечно, вряд ли какое-то из ваших приложений GDI+ будет настолько сложным, как Word. Однако если вам необходимо отображать любой текст, то вам придется решать многие из аналогичных задач.

Короче говоря, корректную высококачественную обработку текста реализовать нелегко. Однако очень просто поместить строку текста на экран, когда известен шрифт и место, где она должна появиться. Поэтому в следующем разделе мы рассмотрим простейший пример, демонстрирующий отображение некоторого текста, за которым последует краткий обзор принципов построения шрифтов и их семейств, а потом- более реалистичный (и сложный) пример приложения, обрабатывающего тексты - CapsEditor.

Простой пример отображения текста

Этот пример, DisplayText, снова будет обычным приложением Windows Forms. На этот раз мы переопределим метод OnPaint() и добавим поля-члены:

private readonly Brush blackBrush = Brushes.Black; private readonly Brush blueBrush = Brushes.Blue;

private readonly Font haettenschweilerFont = new Font( Haettenschweiler , 12); private readonly Font boldTimesFont = new Font( Times New Roman , 10, FontStyle.Bold); private readonly Font italicCourierFont = new Font( Courier , 11, FontStyle.Italic

FontStyle.Underline); protected override void OnPaint(PaintEventArgs e)

base.OnPaint(e); Graphics dc = e.Graphics;

dc.DrawString( This is a groovy string , haettenschweilerFont, blackBrush, 10, 10);

dc.DrawString( This is a groovy string +

with some very long text that will never fit in the box , boldTimesFont, blueBrush,

new Rectangle(new Point(10, 40), new Size(100, 40)));

dc.DrawString( This is a groovy string , italicCourierFont, blackBrush,

new Point(10, 100));

На рис. 33.15 показан результат выполнения этого примера.



Display Text

Данный пример демонстрирует применение метода Graphics.DrawString() для отображения текста. Метод DrawString() имеет множество перегрузок, три из которых продемонстрированы в коде. Различные перегрузки требуют параметров, указывающих отображаемый текст, шрифт, в котором его следует отобразить, а также кисть, применяемую для конструирования прямых и кривых линий, составляющих каждый символ текста. Для остальных параметров существует несколько альтернативных вариантов. Однако, как правило, имеется также возможность указать Point (или два числа) или Rectangle.

Если вы указываете Point, то левый верхний угол текста размещается в этой точке и просто распространяется от нее вправо и вниз. Если же вы указываете Rectangle, то в этом случае экземпляр Graphics размещает текст внутри указанно прямоугольника. Если же текст не умещается в пределы этого прямоугольника, он будет усечен (см. четвертую строку текста на рис. 33.15). Передача методу DrawString() прямоугольника означает, что процесс рисования будет длиться дольше, потому что DrawString() придется определять места переноса строк. Однако результат выглядит лучше, если строки умещаются в прямоугольник.

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

Рис. 33.15. Результат выполнения примера DisplayText

Шрифты и их семейства

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

Большинство людей, когда их просят назвать какой-нибудь шрифт, могут вспомнить Arial или Times New Roman (если они работают в Windows) либо Times или Helvetica (если они пользователи Mac OS). На самом деле это вовсе не шрифты. Это - семейства шрифтов. Семейство шрифтов определяет в общих терминах визуальный стиль текста и является ключевым фактором общей привлекательности вашего приложения. Большинство из нас легко распознают стили наиболее распространенных семейств шрифтов, даже если не задумываются о них.

Действительный шрифт - это нечто вроде Arial 9-point italic . Другими словами, для конкретного шрифта наряду с именем семейства указывается размер и другие модифицирующие параметры текста. Эти модификации могут описывать полужирный, курсив, подчеркнутый, КАПИТЕЛЬ или подстрочный; это то, что часто называют стилем, хотя в некотором смысле этот термин вводит в заблуждение, потому что визуальное представление в большей степени определяется семейством шрифтов.

Размер шрифта определяется его высотой. Высота измеряется в точках (points) - традиционных единицах измерения, представляющих 1/72 часть дюйма (0,351 мм). То есть 10-точечный шрифт имеет высоту 1/7 дюйма, или приблизительно 3,5 мм. Однако это не означает, что семь строк 10-точечного шрифта уместятся в один дюйм по вертикали на экране или бумаге, потому что между строками должно быть некоторое пространство.



1 ... 8 9 10 [ 11 ] 12 13 14 ... 19

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика