Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Благодарности 25 страница






В приложении DrawBezierApp мы рисуем кривую Безье в обработчике события Paint:

private void Form1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
Pen myPen = new Pen(Color.Black, 2);

PointF startPt = new PointF(40.0F, 80.0F);
PointF control1Pt = new PointF(30.0F, 10.0F);
PointF control2Pt = new PointF(350.0F, 250.0 F);
PointF endPt = new PointF(400.0F, 100.0F);

PointF[] myBezierPoints =
{
startPt,
control1Pt,
control2Pt,
endPt
};

Graphics g=e.Graphics;
g.Clear(Color.White);
g.DrawBeziers(myPen, myBezierPoints);
}

Здесь мы создаем начальную и конечную точки startPt и endPt, через которые проходит наша кривая, а также управляющие точки control1Pt и control2Pt. Координаты всех точек передаются методу DrawBeziers через массив myBezierPoints. Управляющие точки изгибают линию, как бы притягивая ее к себе (рис. 10-15).

Рис. 10-15. Рисование кривой Безье

Канонические сплайны

В отличие от только что рассмотренных кривых линий Безье, линии канонического или обычного сплайна (cardinal spline) проходит через все заданные точки.

Для рисования обычных сплайнов предусмотрены методы DrawCurve и DrawClosedCurve. Первый из этих методов рисует незамкнутую кривую линию (открытый сплайн), а второй — замкнутую (закрытый сплайн).

В простейшем случае методам передается перо и массив соединяемых точек:

public void DrawCurve(Pen, Point[]);
public void DrawCurve(Pen, PointF[]);

public void DrawCurveClosed(Pen, Point[]);
public void DrawCurveClosed(Pen, PointF[]);

Существуют версии методов, позволяющие дополнительно задать так называемую жесткость (tension) сплайна. Жесткость задается в виде третьего дополнительного параметра:

public void DrawCurve(Pen, Point[], float);
public void DrawCurve(Pen, PointF[], float);

public void DrawClosedCurve(Pen, Point[], float, FillMode);
public void DrawClosedCurve(Pen, PointF[], float, FillMode);

По умолчанию значение жесткости равно 0, 5. При увеличении этого параметра увеличиваются изгибы кривой линии. При жесткости большей 1 или меньшей 0 кривая может превратиться в петлю.

Методу DrawClosedCurve дополнительно задается параметр типа FillMode. Если значение этого параметра равно FillMode.Alternate, при рисовании самопересекающихся замкнутых сплайнов будут чередоваться закрашенные и не закрашенные области. Если же значение этого параметра равно FillMode.Winding, большинство замкнутых областей будет закрашено.

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

using System.Drawing.Drawing2D;

private void Form1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
Pen myPen = new Pen(Color.Black, 2);

PointF pt1 = new PointF(40.0F, 80.0F);
PointF pt2 = new PointF(30.0F, 10.0F);
PointF pt3 = new PointF(350.0F, 250.0F);
PointF pt4 = new PointF(400.0F, 100.0F);

PointF[] myPoints =
{
pt1,
pt2,
pt3,
pt4
};

Graphics g=e.Graphics;
g.Clear(Color.White);
g.DrawClosedCurve(myPen, myPoints, (float)0.3,
FillMode.Alternate);
}

Результат показан на рис. 10-16.

Рис. 10-16. Рисование канонического сплайна

Замкнутый сегмент эллипса

Для рисования замкнутого сегмента эллипса (pie) Вы можете воспользоваться методом DrawPie. Имеется 4 перегруженных варианта этого метода:

public void DrawPie(Pen, Rectangle, float, float);
public void DrawPie(Pen, RectangleF, float, float);
public void DrawPie(Pen, int, int, int, int, int, int);
public void DrawPie(Pen, float, float, float, float, float, float);

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

Для демонстрации возможностей метода DrawPie мы подготовили приложение DrawPieApp. Вот как выглядит обработчик события Form1_Paint этого приложения:

private void Form1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
Pen myPen = new Pen(Color.Black, 2);

int xPos = 10;
int yPos = 10;
int width = 250;
int height = 150;

int startAngle = 20;
int endAngle = 75;

Graphics g=e.Graphics;
g.Clear(Color.White);

g.DrawPie(myPen, xPos, yPos, width, height,
startAngle, endAngle);

g.DrawRectangle(new Pen(Color.Black, 1), xPos, yPos,
width, height);
}

Здесь через переменные xPos, yPos, width и height передаются координаты левого верхнего угла и размеры прямоугольной области, в которую вписывается сегмент эллипса. Переменные startAngle и endAngle задают углы, ограничивающие сегмент.

Для большей наглядности мы рисуем не только сегмент эллипса, но и прямоугольник, в который этот сегмент вписан. Для рисования прямоугольника мы используем линию толщиной 1 пиксел, а для рисования сегмента — два пиксела (рис. 10-17).

Рис. 10-17. Рисование сегмента эллипса

Закрашенные фигуры

В классе Graphics определен ряд методов, предназначенных для рисования закрашенных фигур. Имена некоторых из этих методов, имеющих префикс Fill, мы перечислили в табл. 10‑ 2.

Таблица 10-2. Методы для рисования закрашенных фигур

Метод Описание
FillRectangle Рисование закрашенного прямоугольника
FillRectangles Рисование множества закрашенных многоугольников
FillPolygon Рисование закрашенного многоугольника
FillEllipse Рисование закрашенного эллипса
FillPie Рисование закрашенного сегмента эллипса
FillClosedCurve Рисование закрашенного сплайна
FillRegion Рисование закрашенной области типа Region

Есть два отличия методов с префиксом Fill от одноименных методов с префиксом Draw. Прежде всего, методы с префиксом Fill рисуют закрашенные фигуры, а методы с префиксом Draw — не закрашенные. Кроме этого, в качестве первого параметра методам с префиксом Fill передается не перо класса Pen, а кисть класса Brush.

Пример использования метода FillEllipse мы приводили ранее в разделе «Рисование в окне элемента управления» этой главы. Вот еще один пример:

SolidBrush redBrush = new SolidBrush(Color.Red);
g.FillEllipse(redBrush, 50, 50, 100, 110);

Здесь мы вначале создаем кисть красного цвета как объект класса SolidBrush. Эта кисть затем передается методу FillEllipse в качестве первого параметра. Остальные параметры метода FillEllipse задают расположение и размеры прямоугольника, в который будет вписан эллипс.

Рисование изображений

Рассказывая в [8] о том, как устроена графическая подсистема в ОС Microsoft Windows, и как ей пользоваться, мы отметили, что рисование графических изображений с использованием одного только программного интерфейса Win32 API — не простая задача. Решая ее, программисту приходится учитывать многочисленные детали, имеющие отношение к цветовому разрешению и режимам видеоадаптера. Кроме того, часто приходится работать напрямую с внутренними форматами файлов графических изображений, таких как BMP, GIF, JPEG, PNG и т.д.

Графическая подсистема GDI+, реализованная на платформе Microsoft.NET Frameworks, содержит мощные и удобные средства работы с графикой и графическими изображениями, исключающие для программиста необходимость разбираться с внутренними форматами файлов графических изображений, а также задумываться о таких вещах, как палитры [8].

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

Немного о ресурсах приложения

Если Вы раньше создавали приложения Microsoft Windows, то знаете, что формат загрузочного модуля таких приложений сложнее формата загрузочного модуля программ MS-DOS. Кроме выполняемого кода и констант в загрузочном модуле приложения Microsoft Windows находятся дополнительные данные — ресурсы.

Что такое ресурсы?

Приложение Microsoft Windows может хранить в виде ресурсов текстовые строки, значки, курсоры, графические изображения, меню, диалоговые окна, произвольные массивы данных и т. д. Физически ресурсы находятся внутри exe-файла приложения. Они могут загружаться в оперативную память автоматически при запуске приложения или по запросу приложения (явному или неявному). Такой механизм обеспечивает экономное использование оперативной памяти, так как все редко используемые данные можно хранить на диске и загружать в память только при необходимости.

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

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

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

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

Значки

В этом разделе мы опишем приложение DrawIconApp, предназначенное для демонстрации способов рисования значков, хранящихся в ресурсах приложения.

Создайте приложение DrawIconApp обычным образом, пользуясь мастером проектов. Затем перепишите в каталог проекта любой файл значка, взяв его, например, из каталога значков системы Microsoft Visual Studio.NET.

Далее включите значок в проект приложения, щелкнув название проекта правой клавишей мыши в окне Solution Explorer и выбрав затем строку контекстного меню Add Existing Item. В результате всех этих действий файл значка появится в списке файлов Вашего проекта.

Щелкните этот файл левой клавишей мыши, а затем установите значение свойства Build Action для файла значка равным Embedded Resource (рис. 10-18).

Рис. 10-18. Включение значка в ресурсы приложения

В результате выполнения этих действий файл значка (в нашем случае это был файл FACE02.ICO) будет добавлен в ресурсы приложения.

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

private void Form1_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
Graphics g = Graphics.FromHwnd(this.Handle);
Icon myIcon = new Icon(GetType(), " FACE02.ICO");
g.DrawIcon(myIcon, e.X, e.Y);
}

Этот обработчик получает контекст отображения с помощью метода Graphics.FromHwnd, а затем создает объект класса Icon, представляющий значок. Для создания этого объекта мы использовали конструктор с двумя параметрами.

Через первый параметр конструктору класса Icon мы передаем ссылку на объект-сборку, в котором хранится наш ресурс — значок из файла FACE02.ICO. Мы можем получить такую ссылку при помощи метода GetType.

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

Функция DrawIcon рисует значок myIcon в точке, где был курсор мыши в момент щелчка (рис. 10-19).

Рис. 10-19. Использование метода DrawIcon

Всего существует два перегруженных метода DrawIcon:

public void DrawIcon(Icon, Rectangle);
public void DrawIcon(Icon, int, int);

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

Независимо от значка myIcon, фрагмент кода, приведенный ниже, рисует в левом верхнем углу значок с размерами 100x100 пикселов:

g.DrawIcon(myIcon, new Rectangle(0, 0, 100, 100));

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

Для рисования значков можно также использовать метод DrawIconUnstretched:

public void DrawIconUnstretched(Icon, Rectangle);

Этот метод рисует значок внутри области, заданной с помощью второго параметра. В отличие от метода DrawIcon, метод DrawIconUnstretched не растягивает и не сжимает значок, а рисует его в точном соответствии с оригинальными размерами значка.

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

Растровые и векторные изображения

В ОС Microsoft Windows используются два формата изображений — аппаратно-зависимый DDB (Device-Dependent Bitmap) и аппаратно-независимый DIB (Device-Independent Bitmap).

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

Если бы в Microsoft Windows можно было работать только с изображениями DDB, было бы необходимо иметь отдельные наборы изображений для каждого типа видеоадаптера и каждого видеорежима, что, очевидно, крайне неудобно.

Аппаратно-независимое изображение DIB содержит описание цвета пикселов изображения, которое не зависит от особенностей устройства отображения. ОС Microsoft Windows после соответствующего преобразования может нарисовать такое изображение на любом устройстве вывода. Несмотря на некоторое замедление процесса вывода по сравнению с выводом изображений DDB, универсальность изображений DIB делает их весьма привлекательными для хранения изображений.

При создании обычных приложений Microsoft Windows, работающих файлами изображений, программисту следовало учитывать, что существует множество форматов таких файлов. Файлы изображений могут содержать таблицу цветов или цветовую палитру, могут быть сжаты с использованием тех или иных алгоритмов. Приложение должно также анализировать структуру графических файлов с целью обнаружения возможных ошибок, так как отображение содержимого неправильного файла может создать полный хаос на экране. При необходимости Вы найдете в [8] полную информацию о форматах DDB и DIB.

Кроме растровых изображений используются так называемые векторные изображения. Если растровые изображения содержат описание цвета каждого пиксела, векторные изображения состоят из описаний отдельных графических объектов, из которых состоит изображение. Это могут быть линии, окружности и т. п. Некоторые графические редакторы, например, Corel Draw, Microsoft Draw, Microsoft Visio, для внешнего представления изображения используют векторный формат.

Сравнивая эти форматы, отметим, что каждый из них имеет свои преимущества и свои недостатки.

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

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

Как мы уже говорили, графический интерфейс GDI+, реализованный компанией Microsoft на платформе Microsoft.NET Frameworks, значительно облегчает работу с изображениями, как растровыми, так и векторными. В табл. 10-4 мы привели полный список форматов графических файлов, с которыми могут работать приложения GDI+. Эти форматы определены в виде свойств статического класса ImageFormat.

Таблица 10-4. Доступные форматы графических файлов

Свойство Описание формата
Bmp Растровые изображения DIB (Device-Independent Bitmap)
Emf Расширенный формат EMF (Windows Enhanced Metafile)
Exif Формат для обмена файлами изображений EXIF (Exchangeable Image File)
Gif Формат обмена графическими изображениями GIF (Graphics Interchange Format)
Icon Значки ОС Microsoft Windows
Jpeg Формат, созданный объединенной группой экспертов по обработке фотографий JPEG (Joint Photographic Experts Group)
MemoryBmp Изображения DIB, создаваемые в оперативной памяти
Png Формат переносимых сетевых изображений PNG (Portable Network Graphics), разработанный группой W3C
Tiff Теговый формат файлов изображений TIFF (Tag Image File Format)
Wmf Метафайл Windows WMF (Windows metafile)

Как видите, список довольно внушительный и включает в себя практически все наиболее распространенные форматы файлов. Все эти форматы, за исключением WMF и EMF, являются растровыми.

Использование класса Image

Для рисования изображений, загруженных из файлов с форматами, перечисленными в табл. 10‑ 4, поможет класс Image. В этом разделе мы создадим приложение ImageViewApp, способное показывать содержимое графических файлов, значки которых перетаскиваются в окно приложения из папок ОС Microsoft Windows методом буксировки. Вы сможете убедиться, что отображение графических изображений в программах C# действительно не вызывает никаких затруднений.

Попутно мы расскажем об использовании буксировки в приложениях Microsoft.NET Frameworks.

Режим буксировки

Если Вы когда-либо сталкивались с необходимостью писать обычные приложения Microsoft Windows, способные обрабатывать файлы или другие объекты, значки которых перетаскиваются пользователем в окно приложения методом буксировки, то знаете, насколько это непросто. Фактически при этом необходимо реализовать в своем приложении OLE-сервер, а эта задача доступна только опытным и очень опытным программистам, владеющим всеми тонкостями модели компонентного объекта (COM, Component Object Model), реализованной в ОС Microsoft Windows.

К счастью, при создании приложений Microsoft.NET Framework эта задача решается очень и очень просто. Мы покажем ее решение на примере упомянутого выше приложения ImageViewApp, предназначенного для просмотра содержимого файлов графических изображений. Нам необходимо сделать так, чтобы пользователи могли перетаскивать значки изображений в окно нашего приложения из папок ОС Microsoft Windows для просмотра.

Итак, с помощью мастера проектов создайте приложение ImageViewApp.

Для того чтобы главное окно нашего приложения могло принимать объекты, перетаскиваемые методом буксировки, установите значение свойства AllowDrop равным True, как это показано на рис. 10-20.

Рис. 10-20. Включение режима AllowDrop

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

События при буксировке

Далее нам необходимо предусмотреть обработку как минимум двух событий. Это события DragOver и DragDrop.

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

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

Помимо этих событий возникают еще события DragEnter и DragLeave. Первое из них позволяет отслеживать момент входа курсора мыши в область принимающего окна, а второе — когда курсор покидает эту область.

Обработка события DragOver

Для обработки события DragOver мы подготовили метод Form1_DragOver, который Вам нужно добавить в приложение ImageViewApp:

private void Form1_DragOver(object sender,
System.Windows.Forms.DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}

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

Свойство KeyState объекта DragEventArgs несет в себе информацию о том, какой клавишей мыши осуществляется буксировка, и нажаты ли при этом клавиши Shift, Control и Alt. Это свойство представляет собой набор флажков, перечисленных в табл. 10-5.

Таблица 10-5. Флажки свойства KeyState

Бит флажка Описание
  Нажата левая клавиша мыши
  Нажата правая клавиша мыши
  Нажата клавиша Shift
  Нажата клавиша Control
  Нажата средняя клавиша мыши
  Нажата клавиша Alt

В свойствах X и Y объекта DragEventArgs передаются, соответственно, горизонтальные и вертикальные координаты курсора мыши (в экранных координатах). Анализируя эти свойства, программа может принять решение о возможности выполнения операции буксировки в те или иные области окна.

Анализируя свойство Data объекта DragEventArgs с помощью методов GetFormats и GetDataPresent, приложение может определить тип передаваемых ему данных. Описание этих методов Вы найдете в документации.

Свойство AllowedEffects содержит информацию о действиях, которые программа может предпринять с передаваемыми ей данными. Это одна из следующих констант, описанных в табл. 10-6.

Таблица 10-6. Константы перечисления AllowedEffects

Бит флажка Описание
None Приложение не может принять данные, передаваемые методом буксировки
Copy Данные должны быть скопированы в приложение, принимающее объект методом буксировки
Move Данные должны быть перемещены в приложение, принимающее объект методом буксировки
Link Необходимо связать буксируемые данные с принимающим приложением
Scroll Разрешается операция прокрутки содержимого в окне принимающего приложения
All Разрешаются все операции

После анализа содержимого перечисленных выше свойств объекта DragEventArgs программа должна установить значение свойства Effect, разрешив или запретив выполнение той или иной операции. При этом следует использовать константы, перечисленные в табл. 10-6.

В приложении ImageViewApp мы разрешаем копирование буксируемых данных, записывая в свойство Effect константу DragDropEffects.Copy:

e.Effect = DragDropEffects.Copy;

Обработка события DragDrop

Теперь займемся обработкой события DragDrop. Вот соответствующий обработчик:

Image img;

private void Form1_DragDrop(object sender,
System.Windows.Forms.DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
img = Image.FromFile(files[0]);
Invalidate();
}

Если пользователь буксирует в окно приложения файл, то формат данных, извлеченных методом GetData из свойства Data, будет DataFormats.FileDrop. В качестве данных будет выступать массив полных путей к файлам (пользователь может перетаскивать сразу несколько файлов). Если же пользователь перетаскивает в окно приложения выделенный фрагмент текста, формат данных будет DataFormats.StringFormat.

Нас интересует только один файл, т.к. приложение ImageViewApp может показывать за один раз только одно изображение.

Загрузка изображения

Для загрузки изображения в память мы используем очень мощный метод Image.FromFile, передавая ему самый первый путь к файлу, извлеченный из нулевой ячейки массива files:

Image img;

img = Image.FromFile(files[0]);

Этот метод загрузит изображение файла любого типа из набора, перечисленного в табл. 10-4.

После того как изображение будет загружено, наше приложение сообщает о необходимости перерисовки его окна, вызывая для этого метод Invalidate:

Invalidate();

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

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

private void Form1_Resize(object sender, System.EventArgs e)
{
Invalidate();
}

Изменение размеров окна приводит к генерации события Resize, так что Вам остается только предусмотреть для него обработчик Form1_Resize.

Рисование загруженного изображения

И, наконец, вот код обработчика события Form1_Paint, на который возложена работа по рисованию загруженного изображения:

private void Form1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
if(img! = null)
{
RectangleF winRect = new RectangleF(0, 0,
e.Graphics.VisibleClipBounds.Width,
e.Graphics.VisibleClipBounds.Height);

SizeF size = new SizeF(img.Width / img.HorizontalResolution,
img.Height / img.VerticalResolution);

float scale = Math.Min(winRect.Width / size.Width,
winRect.Height / size.Height);

size.Width *= scale;
size.Height *= scale;

e.Graphics.DrawImage(img,
winRect.X + (winRect.Width - size.Width) / 2,
winRect.Y + (winRect.Height - size.Height) / 2,
size.Width, size.Height);
}
}

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

Получив управление, метод Form1_Paint проверяет, загрузил ли пользователь какое-либо изображение для рисования. Если загрузил, то метод Form1_Paint определяет границы прямоугольной области, занимаемой клиентской областью окна нашего приложения:

RectangleF winRect = new RectangleF(0, 0,
e.Graphics.VisibleClipBounds.Width,
e.Graphics.VisibleClipBounds.Height);

Именно в этой области и будет нарисовано изображение, файл которого пользователь отбуксировал мышью.

Обычно программы, предназначенные для просмотра изображений, умеют масштабировать их таким образом, чтобы изображение полностью помещалось в окне приложения. Чтобы реализовать необходимую логику масштабирования, нам нужно знать некоторые атрибуты загруженного изображения. Эти атрибуты доступны приложению как свойства класса Image.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.