Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Продолжение создания собственного графического редактораСодержание книги
Поиск на нашем сайте
Теперь мы рассмотрели большинство вопросов, связанных с графикой. Можно вернуться к созданному нами ранее собственному графическому редактору и попробовать его усовершенствовать. Редактор этот чисто демонстрационный и поэтому в нем нет многого, что должно быть в настоящем графическом редакторе. К тому же и тот инструментарий, который в нем имеется, надо бы было реализовать компактнее и с большей надежностью. Но в данном случае, как и во всех демонстрационных примерах, функциональность принесена в жертву простоте и наглядности кода. Тем не менее мы не будем подробно анализировать текст этого приложения. Рассмотрим только основные приемы, которые использованы при создании различных инструментов. А общую логику работы вы можете придумать сами или позаимствовать ее из примера. Приложение выполняет следующие функции: • Установка основного и дополнительного цветов. Щелчок на панели цветов левой кнопкой мыши устанавливает основной цвет, а щелчок правой кнопкой — вспомогательный. • Кисть — кнопка SBBrush. Закрашивает замкнутую область, ограниченную цветом того пикселя, который указан щелчком мыши. При щелчке левой кнопкой закрашивание производится основным цветом, при щелчке правой кнопкой — вспомогательным. • Индикация цвета — кнопка SBColor. В этом режиме вы можете указать курсором мыши любой пиксель на изображении и, щелкнув левой кнопкой, установить цвет этого пикселя как основной, а щелкнув правой кнопкой, установить его как вспомогательный цвет. • Карандаш — кнопка SBPen. В этом режиме вы можете рисовать произвольную кривую основным цветом. • Выделение фрагмента — кнопка SBRect. Фрагмент выделяется точечной рамкой. Выделенный фрагмент можно в дальнейшем перетащить мышью на другое место. Если в процессе перетаскивания нажата клавиша Ctrl, то производится копирование фрагмента, в противном случае — вырезание, при котором область начального размещения фрагмента закрашивается вспомогательным цветом. Выделенный фрагмент может быть также скопирован или вырезан в буфер обмена Clipboard соответствующими командами меню. • Стирание изображения (ластик) —кнопка SBErase. Перемещение ластика закрашивает область под ним во вспомогательный цвет. • Рисование прямоугольника — кнопка SBRectang. Рисуется прямоугольная рамка основным цветом. • Рисование заполненного прямоугольника — кнопка SBFillRec. Рисуется прямоугольная рамка основным цветом и прямоугольник внутри закрашивается вспомогательным цветом. • Рисование прямой линии — кнопка SBLine. Рисуется прямая линия основным цветом. • Открытие графического файла — команда Файл | Открыть. • Сохранение изображения в графическом файле — команда Файл | Сохранить как.... • Отмена операций, выполненных последним использованным инструментом — команда Правка | Отменить. • Копирование или вырезание выделенного фрагмента изображения в буфер обмена Clipboard — команды Правка | Копировать или Правка | Вырезать. • Вставка графического изображения типа битовой матрицы из буфера обмена Clipboard — команда Правка | Вставить. Начнем с рассмотрения функции выделения фрагмента. Она осуществляется методом DrawFocusRect. В этом режиме при событии OnMouseDown холста компонента Image3, выполняются операторы: // запоминание начального положения курсора мыши ХО:=Х;,YO:=Y; // формирование начального положения области фрагмента R.TopLeft!= Point(X,Y); R.BottomRight:= Point(X,Y); // рисование рамки ImageS.Canvas.DrawFocusRect(R); RBegin:= true; Эти операторы запоминают координаты мыши X и Y в переменных ХО и YO, задают начальные координаты прямоугольной области — переменной R типа TRect и рисуют рамку (пока нулевого размера) методом DrawFocusRect. Устанавливается также флаг начала выделения фрагмента — переменная RBegin. При событии OnMouseMove компонента Image3, если установлен флаг RBegin, выполняются операторы: // стирание прежней рамки Image3.Canvas.DrawFocusRect(R); // формирование области R if ХО < X then begin R.Left:= ХО; R.Right:= X end else begin R.Left:= X; R.Right:= XO end; if YO < Y then begin R.Top:= УО; R.Bottom:= Y end else begin R.Top:= Y; R.Bottom:= YO end; // рисование новой рамки Image3.Canvas.DrawFocusRect(R); Первый из этих операторов стирает прежнее изображение рамки (напомним, что метод DrawrFocusRect рисует рамку с помощью операции XOR). Два следующих оператора формируют новую область R из начальных координат (ХО, YO) и текущих координат курсора (X, Y). Дело в том, что область, передаваемая в функцию DrawFocusRect, должна быть сформирована «правильно» — значение R.Left должно быть меньше R.Right, a R.Top — меньше R.Bottom. А поскольку пользователь может перемещать курсор в любом направлении и соотношение координат (ХО, YO) и (X, Y) может быть любым, требуется упорядочивание координат. Последний оператор рисует рамку в новом положении. Итак, рамка, ограничивающая фрагмент, нарисована. Теперь рассмотрим процедуру перетаскивания пользователем выделенного фрагмента. Если пользователь помещает курсор внутрь выделенной области и нажимает кнопку мыши, выполняются операторы: with Image3.Canvas do begin // стирание,.прежней рамки DrawFocusReet(R); // установка флага перетаскивания RDrag:= true; // запоминание начального положения курсора мыши ХО:= X; У0:= Y; //запоминание начального положения перетаскиваемого фрагмента RO.TopLeft:= R.TopLeft; RO.BottomRight:= R.BottomRight; // запоминание изображения BitMap. Assign'(Image3.Picture); // установка, цвета кисти-Brush. Color:= Image2.Canvas.Brush.Color; end; Первый оператор стирает рамку. Второй— устанавливает флаг перетаскивания — переменную RDrag. Два следующих оператора запоминают начальное положение перетаскиваемого фрагмента в переменной RO типа TRect. Следующий оператор запоминает методом Assign изображение в момент начала перетаскивания в переменной BitMap. Это необходимо, чтобы в процессе перетаскивания можно было восстанавливать испорченные места изображения и чтобы при желании пользователя можно было в дальнейшем отменить результат перетаскивания. Последний оператор задает цвет кисти равным вспомогательному цвету, хранящемуся в компоненте Image2. При событии OnMouseMove компонента Image3, если установлен флаг RDrag, выполняются операторы: // восстановление изображения под перетаскиваемым фрагментом. CopyRect (R,BitMap.Canvas,R); // если не нажата клавиша Ctrl - стирание изображения в .RO if not (ssCtrl in Shift) then FillRect (RO); // формирование нового положения фрагмента R.Left:= R.Left + X - ХО; R.Right:= R.Right + X - XO; R.Top:= R.Top + Y - YO; R.Bottom:= R.Bottom + Y - YO; // запоминание положения курсора мыши ХО:= X; YO:= Y; // рисование фрагмента в новом положении CopyRect(R,BitMap.Canvas,R0); // рисование рамки DrawFocusRect (R); Первый оператор восстанавливает изображение под перетаскиваемым фрагментом в его прежней позиции (т.е. стирает фрагмент), копируя соответствующую область методом CopyRect из компонента BitMap. Далее, если не нажата клавиша Ctrl, то очищается область начального размещения фрагмента (осуществляется вырезание) методом FillRect. Затем запоминаются новые координаты курсора и новое положение фрагмента, после чего фрагмент и его рамка рисуются в новом положении. Вот в общих чертах и все, что надо сделать для осуществления наиболее сложных операций — выделения фрагмента и его перетаскивания. Режимы рисования заполненного и не заполненного прямоугольников проще. Начало этих режимов по событию OnMouseDown и их продолжение по событиям OnMouseMove не отличаются от рассмотренного ранее режима выделения фрагмента. Отличие только в том, что при завершении формирования пользователем прямоугольной рамки, т.е. при событии OnMouseUp, надо в данном случае нарисовать прямоугольник. Рисование заполненного прямоугольника осуществляется операторами: with Image3.Canvas do begin; Brush.Color:= Image2.Canvas.Brush.Color; Pen.Color:= Imagel.Canvas.Brush.Color; Rectangle(R.Left,R.Top,R.Right,R.Bottom); end; Они задают цвета кисти и пера и рисуют прямоугольник методом Rectangle. Рисование не закрашенного прямоугольника осуществляется операторами: with Image3.Canvas do begin Brush.Color:= Imagel.Canvas.Brush.Color; FrameRect(R); end; Обратите внимание, что равным основному цвету задается цвет кисти, а не пера, поскольку метод FrameRect рисует цветом кисти. Рисование прямой линии осуществляется следующим образом. Начало рисования по событию OnMouseDown сводится к операторам: ХО:= X; YO:= Y; XI:= X; Y1:= Y; Image3.Canvas.Pen.Color:= Imagel.Canvas.Brush.Color; Image3.Canvas.Pen.Mode:= pmNotXor; Они запоминают положение курсора в двух наборах переменных: (ХО, YO) и (XI, Y1). Зачем нужны два набора — будет сказано позднее. Затем устанавливается цвет пера и режим pmNotXor, который позволит при движении мыши стирать изображение линии. При событиях OnMouseMove работают следующие операторы: with Image3.Canvas do begin // стирание прежней линии MoveTo(ХО,YO); LineTo(XI,Yl); // рисование новой линии MoveTo(ХО,YO); LineTo(X,Y); // запоминание новых координат конца линии XI:= X; Yl:= Y; end; В этих операциях сначала парой методов MoveTo и LineTo стирается линия в прежнем положении, а затем такой же парой методов рисуется новая линия. После этого запоминаются новые координаты конца линии. Попробуем разобраться, зачем все так сложно. Ведь казалось бы, что достаточно всего двух операторов: LineTo (XO,YO); LineTo(X,Y); Первый из них сотрет прежнюю линию, поскольку текущая позиция пера после рисования этой прежней линии соответствовала концу линии (тем координатам, которые мы храним в переменных XI, Y1). А второй оператор нарисует новую линию. И не надо хранить никаких координат. Так просто нельзя сделать из-за одной тонкости: метод LineTo рисует линию, начинающуюся в текущей позиции пера и заканчивающуюся в указанной точке, исключая эту конечную точку. Поэтому, если выполнить в режиме pmNotXor приведенные выше операторы, то первый из них сотрет прежнюю линию, но оставит нестертой точку с координатами (X0, Y0) и, кроме того, нарисует точку в бывшей позиции курсора, поскольку она, как конечная, была исключена при рисовании предыдущей линии. Таким образом, на концах линии останется «грязь» в виде концевых точек, которая и будет тянуться за перемещающимся курсором мыши. Заключительные операции при событии OnMouseUp аналогичны рассмотренным выше, но дополняются переводом пера в режим рmСору, при котором рисуется окончательная линия: with Imaige3.Canvas do begin // стирание прежней линии MoveTo(XO,YO); LineTo(XI,Yl); // рисование новой линии Pen.Mode:= pmCopy; MoveTo(XO,YO); LineTo(X,Y); end; Теперь рассмотрим инструмент Перо, позволяющий рисовать произвольные линии. Казалось бы естественной реализацией этого инструмента был бы оператор Image3.Canvas.Pixels[X,Y]:= Imagel.Canvas.Brush.Color; который окрашивает пиксель под курсором в основной цвет. Однако попробуйте так реализовать Перо и ничего хорошего не увидите. Курсор мыши перемещается быстро и события OnMouseMove происходят вовсе не при перемещении на соседний пиксель. Линию, оставляемую курсором, следует рисовать тоже методом LineTo, поместив в обработчик события OnMouseMove оператор Image3.Canvas.LineTo(X, Y). Коротко перечислим оставшееся. Ластик реализуется методом FillRect, очищающим изображение под его рамкой. Кисть, отмена команд и загрузка внешнего файла. Сохранение файла осуществляется с использованием компонента типа SavePictureDialog. Изображение с холста сохраняется в компоненте BitMap, из которого методом SaveToFile записывается в выбранный пользователем файл. Команды меню Копировать и Вырезать осуществляются процедурой procedure TForml.MGopyClick(Sender: TObject); var BMCopy: TBitMap; begin // стирание рамки Image3.Canvas.DrawFocusRect(R); // создание временного объекта ВМСору ВМСору:= BitMap.Create; ВМСору.Width:= R.Right - R.Left; ВМСору.Height:= R.Bottom - R.Top; try // копирование фрагмента в BM Сору ВМСору.Canvas.Соругееt(Rect(0,0,ВМСору.Width, ВМСору.Height) Image3.Canvas,R); // восстановление рамки Images.Canvas.DrawFocusRect (R); // копирование в Clipboard ClipBoard.Assign(ВМСору); if (Sender as TMenuItem).Name:= 'MCut' then begin // вырезание Image3.Canvas.Brush.Color:=clWhite; Image3.Canvas.FillRect(R); end; finally // освобождение памяти ВМСору.Free; end; end; Копированию или вырезанию подлежит ранее выделенный пользователем объект, местоположение и размеры которого определяются переменной R. Поэтому сначала создается временный объект типа TBitMap, в который переносится копируемый фрагмент. Затем этот объект копируется в Clipboard. Благодаря разделу finally память освобождается от временного объекта при любом исходе копирования: удачном или аварийном. Аналогично реализуется команда Вставить, копирующая изображение из буфера обмена Clipboard: procedure TForml.MPasteClick(Sender: TObject); var ВМСору:TBitMap; begin ВМСору:=BitMap.Create; try try ВМСору.LoadFromClipBoardFormat(cf_BitMap, ClipBoard.GetAsHandle(cf_Bitmap),0); Image3.Canvas.CopyRect(Rect(0,0,ВМСору.Width, ВМСору.Height), ВМСору.Canvas,Rect(0,0,ВМСору.Width,ВМСору.Height)): finally ВМСору.Free; end; except On EInvalidGraphic do ShowMessage(Ошибочный формат графики); end; end; Чтение из Clipboard осуществляется методом LoadFromClipBoardFormat. Предусмотрен перехват исключения EInvalidGraphic, если в Clipboard содержится не битовая матрица. Попробуйте также усовершенствовать редактор, добавив в него, например, выбор ширины линий, рисование эллипсов и т.д.
Мультимедиа и анимация
Звук
Так же, как существует множество рассмотренных нами форматов графических файлов, существует немало файлов звуковых и мультимедиа. Мы коротко охарактеризуем обе эти группы файлов в рамках данного раздела, так как файлы мультимедиа часто содержат звуковую дорожку и было бы не очень правомерно, говоря о звуке, не упомянуть звук в мультимедиа. Наиболее простым звуковым файлом является волновой файл.wav. В нем записано цифровое представление информации о волновой форме электрического сигнала, соответствующего каждому звуку. Волновой файл «не знает» вообще ничего о том, что такое звук и что он означает; поэтому для хранения звукового клипа приходится запоминать массу информации. Другим часто применяемым типом файлов-носителей являются файлы цифрового интерфейса музыкальных инструментов (MIDI). Файлы.midi используются для хранения музыкальных фрагментов. В этих файлах звук хранится в виде данных о том, на каких инструментах исполняются определенные ноты и как долго они звучат. Одним из главных преимуществ MIDI является то, что файлы получаются сравнительно небольшими. Волновые и MIDI файлы могут хранить только звук или музыку. Для хранения видео информации разработан ряд форматов. Отметим среди них файлы AVI и MPEG. Большинство видеофайлов поддерживают также хранение звуковой дорожки, так что звук воспроизводится синхронно с картинкой. Наиболее простой процедурой, управляющей звуком, является процедура Веер. Она не имеет параметров и воспроизводит стандартный звуковой сигнал, установленный в Windows, если компьютер имеет звуковую карту и стандартный сигнал задан (он устанавливается в программе Windows «Панель управления» после щелчка на пиктограмме Звук). Если звуковой карты нет или стандартный сигнал не установлен, звук воспроизводится через динамик компьютера просто в виде короткого щелчка. Откройте новое приложение, введите в него кнопку, в обработчике щелчка которой напишите одно слово: Веер; Можете запустить приложение, щелкнуть на кнопке и прослушать стандартный звук Windows или просто щелчок, если стандартный звук не установлен. Более серьезной процедурой является MessageBeep. Она определена как function MessageBeep (uType: word).: boolean; Параметр uType указывает воспроизводимый звук как идентификатор раздела [sounds] -реестра, в котором записаны звуки, сопровождающие те или иные события в Windows. С помощью приложения Звук в «Контрольной панели» пользователь может удалить или установить соответствующие звуки. После запроса звука функция MessageBeep возвращает управление вызвавшей функции и воспроизводит звук асинхронно. Во время воспроизведения приложение может продолжать выполняться. Если невозможно воспроизвести указанный в функции звук, делается попытка воспроизвести стандартный системный звук, установленный по умолчанию. Если и это невозможно, то воспроизводится стандартный сигнал через динамик. При успешном выполнении возвращается ненулевое значение. При аварийном завершении возвращается нуль. Можете в своем тестовом приложении ввести еще одну кнопку и написать для нее обработчик: MessageBeep(MB_OK); Вы услышите тот же стандартный звук Windows, что и при выполнении процедуры Веер. Или услышите тот же тихий щелчок, если стандартный звук не установлен. Попробуйте установить различные звуки с помощью «Панели управления» и проверить MessageBeep при различных значениях ее параметра. А теперь давайте займемся более серьезной функцией PlaySound, которая позволяет воспроизводить не только звуки событий Windows, но и любые волновые файлы. Это функция API Windows, параметры которой описаны в модуле mmsystem. Поэтому для использования этой функции в вашем приложении необходимо включить в его оператор uses ссылку на mmsystem, поскольку автоматически эту ссылку Delphi не включает. Функция PlaySound определена следующим образом: function PlaySound (pszSound:PChaf; hmod:HINST; fdwSound: Cardinal): boolean; Параметр pszSound представляет собой строку с нулевым символом в конце и определяет воспроизводимый звук. Параметр hmod используется, если звук берется из ресурса. А поскольку далее звуками из ресурса мы пользоваться не будем, то hmod всегда можно задавать равным nil или 0. Параметр fdwSound является множеством флагов, которые определяют режим воспроизведения и тип источника звука. Ниже приведены некоторые из этих флагов, наиболее важные для воспроизведения произвольных волновых файлов: - SND_ASYNC - Звук воспроизводится асинхронно и функция PlaySound возвращается немедленно после начала воспроизведения. Чтобы прекратить асинхронное воспроизведение волнового файла, надо вызвать PlaySound с параметром pszSound, равным 0. - SNDJLOOP - Воспроизведение звука постоянно повторяется, пока не вызовется PlaySound с параметром pszSound, равным 0. Одновременно надо установить флаг SND_ASYNC асинхронного воспроизведения звука. - SND_NOSTOP - Если заданный звук не может быть воспроизведен, поскольку ресурсы, необходимые для воспроизведения, заняты воспроизведением другого звука, функция PlaySound немедленно вернет false, не воспроизводя заданного звука. Если данный флаг не указан, функция PlaySound пытается остановить воспроизведение другого звука, чтобы устройство могло быть использовано для воспроизведения нового звука. - SND_NOWAIT - Если драйвер занят, функция сразу вернется без воспроизведения заданного звука - SND_PURGE - Останавливается воспроизведение любых звуков, вызванных в данной задаче. Если pszSound не 0, останавливаются все экземпляры указанного звука. Если pszSound равен 0, то останавливаются все звуки, связанные с данной задачей. - SND_SYNC - Синхронное воспроизведение звука события. Функция PlaySound возвращается только после окончания воспроизведения. Флаги могут комбинироваться операцией оr. Звук, указанный параметром pszSound, должен помещаться в доступную память и должен подходить для установленного драйвера устройства воспроизведения волновых файлов. Функция PlaySound ищет файл звука в следующих каталогах: текущем, каталоге Windows, системном каталоге Windows, каталогах, перечисленных в переменной среды PATH, в списке каталогов, предоставляемых сетью. Если указанный звук не находится, функция PlaySound воспроизводит системный звук по умолчанию. Если функция не может найти и его, то воспроизведения не будет, а вернется значение false. Приведем примеры использования функции PlaySound. Оператор PlaySound('c:\win98\media\3вукMicrosoft.wav',О,SND_ASYNC); воспроизводит асинхронно и однократно стандартный звук Microsoft, который вы обычно можете слышать при открытии Windows. В процессе воспроизведения продолжается выполнение приложения. Чтобы опробовать функцию PlaySound, введите в свое приложение диалог OpenDialog и кнопку со следующим обработчиком щелчка: if OpenDialogl.Execute then PlaySound (PChar (Open Dialogl.FileName),0,SND_ASYNC); Запустите приложение, выберите файл какой-нибудь приятной музыки и работайте со своим приложением, наслаждаясь попутно выбранной мелодией. В предыдущих примерах звук задавался именем его волнового файла. Функция PlaySound позволяет воспроизводить и системные звуки, просто называя их псевдонимы. Например, оператор PlaySound('SystemStart',0,SND_ASYNC); воспроизведет тот же звук открытия Windows, что и приведенный ранее оператор, указывавший имя и путь к нему. Оператор PlaySound('с:\win98\media\3вук Microsoft.wav', 0, SND_ASYNC or SND_LOOP); многократно асинхронно воспроизводит стандартный звук Microsoft, начиная его снова и снова, как только он заканчивается. Если вы ввели в свое приложение подобный оператор (пусть даже и с очень приятной музыкой), вам надо предусмотреть еще и какую-нибудь кнопку, по которой воспроизведение прерывается заданием нового звука или выполнением оператора PlaySound(0,0, SND_PURGE); Оператор PlaySound('с:\win98\media\3вук Microsoft.wav, 0, SND_SYNC); будет воспроизводить звук синхронно. Т.е. функция PlaySound не вернется, пока воспроизведение не завершится. На это время ваше приложение будет блокировано. Впрочем, ваши действия во время этого вынужденного простоя запомнятся системой. И если вы, слушая музыку, щелкнули на той же кнопке повторно, то после окончания звука он будет повторен, так как ваш щелчок встал в очередь событий. Все рассмотренные ранее операторы прерывали при своем выполнении звук, который асинхронно воспроизводился в момент вызова PlaySound. Если же вы выполните оператор с флагом SND_NOSTOP, например: PlaySound('с:\win98\media\3вук Microsoft.wav',0, SND_SYNC or. SND_NOSTOP) то в случае, если в этот момент драйвер занят воспроизведением другого звука, это воспроизведение не будет прерываться, а функция PlaySound сразу вернет false. Впрочем, заказанного этим оператором звука вы в этом случае не услышите, т.к. в очередь он не встанет.
|
||||
Последнее изменение этой страницы: 2016-12-28; просмотров: 270; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.137.162.107 (0.01 с.) |