Практическое занятие № 7

 

Тема: Работа с графикой

Цель работы: получить практические навыки по работе с компонентами отображения графических данных

 

Ход работы

 

 

Создайте форму для просмотра графических файлов вида:

 

 

Указания: для формы задайте свойства: Text=Выбор изображения.

Для работы с папками и файлами в C# нет встроенных компонентов, поэтому воспользуемся сторонней библиотекой Shell MegaPack.Net. После установки данной библиотеки на панели компонентов появится новый раздел "Shell MegaPack.Net".

Нанесите на форму компонент FolderView для отображения дерева папок. Нанесите на форму компонент FileView для отображения списка элементов в выбранной папке.

Для связывания дерева папок со списокм єлементов для компонента FolderView задайте свойство: FileView - fileView1.

Для отображения в списке только графических файлов для компонента FileView задайте свойство: FilePattern = "*.bmp;*.jpg;*.gif;*.png".

 

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

 

Указания: нанесите на форму компонент PictureBoxи задайте свойство: SizeMode = Zoom (масштабирование с сохранением пропорций рисунка).

 

Отображение файла в компоненте PictureBox должно выполняться после щелчка на файле в списке. При этом нужно обработать ситуацию, при которой пользователь выберет папку или щелкнет на пустом месте. Для этого в событии AfterSelectionChange (после выбора нового элемента в списке) компонента FileView введите код:

 

private void fileView1_AfterSelectionChange(object sender, LogicNP.FileViewControl.FileViewEventArgs e)

{

    //если выбранный элемент не папка и не пустое место  

    if (!e.Item.IsFolder() && e.Item!=null)

        //загружаем в PictureBox файл по выбранному пути       

        pictureBox1.Image = Image.FromFile(e.Item.Path);

}

 

По двойному щелчку на компоненте PictureBox открывается новое окно с увеличенным изображением.

 

Указания: добавьте в проект новую форму (перейдите на закладку "Обозреватель решений", в контекстном меню проекта выберите команду "Добавить - Создать элемент", в новом окне укажите "Форма Windows Form". Для формы задайте свойства: Text = Просмотр изображения, StartupPosition = CenterScreen.

Нанесите на форму компонент PictureBox и задайте для него свойства: Dock = заполнение всей формы, SizeMode = Zoom (масштабирование с сохранением пропорций).

Перейдите на главную форму Form1 и для компонента PictureBox  в событии DoubleClick введите код:

 

private void pictureBox1_DoubleClick(object sender, EventArgs e)

{

    //если PictureBox пустой, то завершаем работу   

    if (pictureBox1.Image == null)

        return;

    //создаем экземпляр формы в памяти   

    Form2 form2 = new Form2();

    //в компонент PictureBox созданной формы загружаем изображение с главной формы   

    form2.pictureBox1.Image = pictureBox1.Image;

    //отображаем созданную форму как модальную   

    form2.ShowDialog();

}

 

Так как мы обращаемся к компоненту PictureBox на второй форме, то этот компонент нужно сделать доступным (по умолчанию все компоненты имеют уровень доступа Private). Перейдите на вторую форму и для компонента PictureBox установите свойство: Modifiers = Public.

 

При закрытии второй формы она должна удаляться из памяти.  Перейдите на вторую форму и в событии FormClosed введите код:

private void Form2_FormClosed(object sender, FormClosedEventArgs e)

{

    //удалить форму из памяти

    Dispose();

}

 

Для выполнения работы с изображением на главной форме для компонента Image создадим контекстное меню.

 

 

Указания: нанесите на форму компонент CjntextMenuStrip. С помощью свойства Items войдите в редактор меню. В выпадающем списке укажите тип элемента меню (MenuItem - команда меню, Separator - разделитель) и по кнопке Добавить создайте команды, показанные на рисунке. При этом каждый пункт меню имеет свойство Text для изменения  надписи.

Для присваивания созданного контекстного меню для компонента PictureBox задайте свойство свойстве ContextMenuStrip = contextMenuStrip1. 

 

Команды контекстного меню нужно блокировать и разблокировать в зависимости от состояния изображения и буфера обмена.

 

В событии Opening компонента ContextMenuStrip введите код:

 

private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)

{

    //если изображения в PictureBox нет

    if (pictureBox1.Image == null)

    {

        //блокируем команды Сохранить, вырезать, Копировать, Изменить размер

        toolStripMenuItem1.Enabled =

        toolStripMenuItem2.Enabled =

        toolStripMenuItem3.Enabled =

        toolStripMenuItem5.Enabled = false;

    }

    //в противном случае разблокируем эти команды

    else

    {

        toolStripMenuItem1.Enabled =

        toolStripMenuItem2.Enabled =

        toolStripMenuItem3.Enabled =

        toolStripMenuItem5.Enabled = true;

    }

 

    //если в буфере обмена не картинка

    if (Clipboard.GetImage()==null)

        //блокируем команду Вставить

        toolStripMenuItem4.Enabled = false;

    //иначе разблокируем команду Вставить

    else

        toolStripMenuItem4.Enabled = true;

}

 

Команда Сохранить... должна выдавать диалог и предлагать пользователю выбрать один из 4 типов файлов.

 

Указания: нанесите на форму компонент SaveFileDialog. Для компонента задайте свойства: Filter = "BMP рисунок|*.bmp|JPEG рисунок|*.jpg|GIF рисунок|*.gif|PNG рисунок|*.png" - список форматов для сохранения, DefaultExt = bmp - тип файла по умолчанию.

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

 

private void toolStripMenuItem1_Click(object sender, EventArgs e)

{

    //в диалоге сохранения очищаем имя файла

    saveFileDialog1.FileName = "";

    //если в диалоге сохранения указано имя файла

    if (saveFileDialog1.ShowDialog()==DialogResult.OK)

        //то проверяем номер указанного типа файла из фильтра (нумерация с 1)

        switch (saveFileDialog1.FilterIndex)

        {

            //если указан первый тип (bmp)

            case 1:

                //задаем расширение по умолчанию

                saveFileDialog1.DefaultExt = "bmp";

                //сохраняем содержимое PictureBox в формат BMP

                pictureBox1.Image.Save(saveFileDialog1.FileName,

                                        System.Drawing.Imaging.ImageFormat.Bmp);

                break;

        //аналогично, если выбран 2 тип (jpg)

        case 2:

            saveFileDialog1.DefaultExt = "jpg";

            pictureBox1.Image.Save(saveFileDialog1.FileName,

                                        System.Drawing.Imaging.ImageFormat.Jpeg);

            break;

        //аналогично, если выбран 3 тип (gif)

        case 3:

            saveFileDialog1.DefaultExt = "gif";

            pictureBox1.Image.Save(saveFileDialog1.FileName,

                                        System.Drawing.Imaging.ImageFormat.Gif);

            break;

        //аналогично, если выбран 4 тип (png)

        case 4:

            saveFileDialog1.DefaultExt = "png";

            pictureBox1.Image.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Png);

            break;

        }

}

 

Реализуйте возможность работы с графикой через буфер обмена.

 

Указания: ддля команды Вырезать напишите код:

 

private void toolStripMenuItem2_Click(object sender, EventArgs e)

{

    //записываем в буфер обмена содержимое PictureBox

    Clipboard.SetImage(pictureBox1.Image);

    //очищаем PictureBox

    pictureBox1.Image = null;

}

 

Для команды Копировать напишите код:

 

private void toolStripMenuItem3_Click(object sender, EventArgs e)

{

    //записываем в буфер обмена содержимое PictureBox

    Clipboard.SetImage(pictureBox1.Image);

}

 

Для команды Вставить напишите код:

 

private void toolStripMenuItem4_Click(object sender, EventArgs e)

{

    //в PictureBox записываем содержимое буфера обмена

    pictureBox1.Image = (Image)Clipboard.GetImage();

}

 

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

 

Указания: создайте новую форму (см. создание второй формы). Для новой формы задайте свойства: Text = Новый размер, FormBorderStyle = FixedDialog, StartupPosition = CenterScreen.  Для команды "Изменить размер..." введите код:

 

private void toolStripMenuItem5_Click(object sender, EventArgs e)

{

    //создаем в памяти экземпляр формы

    Form3 form3 = new Form3();

    //отображаем форму как модальную

    form3.ShowDialog();

}

 

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

 

Указания:  откройте файл проекта Program.cs.

После строки заголовка класса проекта

 

static class Program

 

опишите глобальную переменную для доступа к главной форме в проекте

 

public static Form1 form1;

 

Замените команду

 

Application.Run(new Form1());

 

на команды

 

Program.form1 = new Form1();

Application.Run(form1);

 

После этого к главной форме проекта можно обратиться по имени Program.form1

 

 

Форму задания размера файла оформите как показано на рисунке. При открытии формы поля Ширина и Высота должны автоматически заполняться реальными размерами изображения, отображаемого в компоненте PictureBox главной формы. При вводе ширины или высоты значение в соседнем поле должно автоматически изменяться с соблюдением пропорций рисунка.

 

 

Указания: нанесите на форму две надписи, два текстовых поля и две кнопки. Первая кнопка реагирует на нажатие Enter, вторая - Escape. Для этого у формы установите свойства: AcceptButton = button1, CancelButton = button2.

 

Для сохранение пропорций сторон рисунка опишем глобальную переменную для хранения коэффициента соотношения сторон:

 

double p;

 

В событии Load формы заполним поля  реальными размерами изображения и вычислим коэффициент пропорции.

 

private void Form3_Load(object sender, EventArgs e)

{

    //для обращения к главной форме будем использовать имя Program.form1

 

    //заполняем поле ширины

    textBox1.Text = Program.form1.pictureBox1.Image.Width.ToString();

    //заполняем поле высоты

    textBox2.Text = Program.form1.pictureBox1.Image.Height.ToString();

    //рассчитываем коээфициент пропорции (ширина/высота)

    p = Convert.ToDouble(textBox1.Text) / Convert.ToDouble(textBox2.Text);

}

 

Так как мы в коде третьей формы обращаемся к компоненту PictureBox главной формы, то этот компонент нужно сделать "видимым". Перейдите на главную форму и для компонента PictureBox укажите свойство: Modifiers = Public.

 

При изменении значения ширины высота должна автоматически пересчитываться с учетом коэффициента. В событии KeyUp поля textBox1 введите код:

 

private void textBox1_KeyUp(object sender, KeyEventArgs e)

{

    //если поле ширины пустое, завершаем работу

    if (textBox1.Text=="")

        return;

    //высота равна как ширина / коэффициент

    textBox2.Text=Convert.ToInt32(Convert.ToDouble(textBox1.Text)/p).ToString();

}

 

При изменении значения  высоты ширина должна автоматически пересчитываться с учетом коэффициента. В событии KeyUp поля textBox2 введите код:

 

private void textBox2_KeyUp(object sender, KeyEventArgs e)

{

    //если поле высоты пустое, завершаем работу

    if (textBox2.Text=="")

        return;

    //ширина равна как высота * коэффициент

    textBox1.Text=Convert.ToInt32(Convert.ToDouble(textBox2.Text)*p).ToString();

}

 

Кнопка Отмена закрывает окно.

 

private void button2_Click(object sender, EventArgs e)

{

    Close();

}

 

При закрытии формы она должна удаляться из памяти. В событии FormClosed формы введите код:

 

private void Form3_FormClosed(object sender, FormClosedEventArgs e)

{

    Dispose();

}

 

Кнопка ОК изменяет размер рисунка и помещает его в компонент PictureBox на главной форме.

 

private void button1_Click(object sender, EventArgs e)

{

    //если ширина или высота не указаны, завершаем работу

    if (textBox1.Text == "" || textBox2.Text == "")

        return;

 

    //создаем новый экземпляр класса Bitmap

    //в него загружаем содержимое компонента PictureBox главной формы

    //в качестве новой ширины подставляем textBox1

    //в качестве новой высоты подставляем textBox2

    Bitmap temp = new Bitmap(Program.form1.pictureBox1.Image,

                              Convert.ToInt32(textBox1.Text),

                              Convert.ToInt16(textBox2.Text));

    //полученное изображение помещаем в PictureBox на главной форме

    Program.form1.pictureBox1.Image = temp;

    //закрываем окно

    Close();

}