Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Inf_2.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
264.7 Кб
Скачать

Компонент tImage

Этот компонент служит надстройкой над классом TPicture и замыкает всю иерархию графических объектов VCL. Именно на его поверхности и будут отображаться графические объекты, содержащиеся в свойстве:

property Picture: TPicture;

В качестве канвы компонента (свойство canvas) используется канва объекта из свойства picture. Graphic, но только если поле Graphic ссылается на объект класса TBitmap. Если это не так, то попытка обращения к свойству вызовет исключительную ситуацию Einvalidoperation, так как рисовать на метафайле или значке нельзя.

Следующие три свойства определяют, как именно графический объект располагается в клиентской области компонента:

  • property AutoSize: Boolean;

Означает, что размеры компонента настраиваются по размерам содержащегося в нем графического объекта. Устанавливать его значение равным True нужно перед загрузкой изображения из файла или буфера обмена;

  • property Stretch: Boolean;

Если значение этого свойства установлено равным True, то изображение "натягивается" на клиентскую область, при необходимости уменьшая или увеличивая свои размеры. Если оно равно False, то играет роль следующее свойство:

property Center: Boolean;

Если это свойство равно True, изображение центрируется в пределах клиентской области. В противном случае оно располагается в ее верхнем левом углу.

Несмотря на то что описанию свойств и методов графических объектов здесь отведено уже довольно много места, работа с ними проста и удобна. Программу для просмотра изображений в среде Delphi можно создать буквально "в три счета":

  1. Поместите на форму следующие компоненты: область прокрутки TScroiiBox, на нее — компонент Timage (их верхние левые углы должны совпадать), любую кнопку (например, TButton) и диалог открытия файлов TOpenPictureDialog.

  2. Подключите к главному модулю создаваемого приложения модуль JPEG (в предложении uses); значение свойства Autosize компонента Timage установите равным True.

  3. Дважды щелкните мышью на кнопке. В появившемся обработчике события onciick напишите такой код:

procedure TForml.BitBtnIClick(Sender: TObject);

begin

OpenPictureDialogI.Filter := GraphicFilter(TGraphic);

if OpenPictureDialogI.Execute

then Imagel.Picture.LoadFromFile(

OpenPictureDialogI.FileName);

end;

Приложение готово. Обратите внимание на роль полиморфизма в методе LoadFromFile — по расширению файла определяется его формат и в зависимости от этого создается нужный графический объект.

Использование диалогов для загрузки и сохранения графических файлов

Для удобства открытия картинок существует пара компонентов-диалогов:

TOpenPictureDialog И TSavePictureDialog.

Список форматов открываемых файлов определяется свойством Filter. Можно, как в случае со стандартными диалогами TOpenDialog или TSaveDialog, сформировать их вручную с помощью редактора свойства Filter. Можно поступить проще, воспользовавшись готовыми средствами. Для удобства формирования строк графических фильтров существуют три специальные функции:

  • function GraphicFilter(GraphicClass: TGraphicClass): string;

Формирует строку с полным текстом графического фильтра, позволяющего открывать все файлы, форматы которых являются потомками параметра GraphicClass. Если в качестве параметра этой функции будет передан класс TGraphic, то в строке будут перечислены все форматы:

'All

(*.jpg;*.jpeg;*.bmp;*.ico;*.emf;*.wmf)|*.jpg;

*.jpeg;*.bmp;*.ico;*.emf;

*.wmf|JPEG Image File (*.jpg)|*.jpg|JPEG Image File (*.jpeg)|*.jpeg|Bitmaps (*.bmp)|*.brnplIcons (*.ico)I*.ico Enhanced Metafiles (*.emf)I*.emf|Metafiles (*.wmf)|*.wmf

Формат JPEG появляется в перечне, если в приложении используется модуль с тем же названием — JPEG. В приводимом ниже примере возникла необходимость совместить фильтры только для классов TBitmap и

TJPEGlmage, которые не являются предками друг друга. В этом случае получившиеся строки нужно соединить, используя символ конкатенации (|):

S := GraphicFilter(TBitmap)+'|'+GraphicFilter(TJpegImage) D function GraphicExtension(GraphicClass: TGraphicClass): string;

Возвращает расширение файла, формат которого соответствует графическому классу GraphicClass. Так, если передать в качестве параметра класс TBitmap, то функция вернет строку 'bmp' ;

  • function GraphicFileMask(GraphicClass: TGraphicClass): string;

Эта функция возвращает перечень расширений файлов с форматами — потомками GraphicClass, перечисленных через точку с запятой.

Для диалогов предусмотрено несколько событий, которые программист может обработать самостоятельно. Первые три — достаточно тривиальные: onshow, OnCanciose и enclose. Нужно предостеречь программиста: по чьему-то недосмотру последние два события вызываются только в случае нормального завершения диалога (нажатием кнопки Open или Save), а если завершить диалог нажатием кнопки Cancel или крестика на заголовке диалога, управления они не получат.

Другие три события связаны с изменениями, которые осуществляет пользователь во время выбора нужного файла. Они происходят в момент изменения формата открываемого файла (событие onTypeChange), изменения текущей папки (OnFolderChange) И текущего файла (OnSelectionChange).

Но разработчики диалогов не предусмотрели одну очень нужную возможность. Дело в том, что у разных графических форматов возможны различные параметры и варианты. Если вы имеете опыт работы с графическими пакетами вроде Adobe Photoshop или Corel, то знаете, что в зависимости от выбранного формата сохранения данных диалоговое окно изменяет свой внешний вид — к нему добавляются элементы управления, соответствующие параметрам формата.

Поступим так и мы, предусмотрев настройку при сохранении файлов формата JPEG. Для этого будет использовано событие OnTypeChange компонента TSavepietureDiaiog. Для события нужно проверить значение свойства Filterindex. Если оно больше 1 (то есть выбраны файлы формата JPEG), нужно увеличить высоту окна диалога и разместить на нем дополнительные компоненты: флажок, соответствующий свойству progressiveEncoding, и редактор свойства CompressionQuality (рис. 8.2). Если тип файла снова поменялся и стал равным 1, нужно эти компоненты убрать.

Поможет нам в этом внимательное изучение исходных кодов диалогов, находящихся в модуле extdlgs.pas. Программисты Inprise пошли по пути модернизации внешнего вида стандартных диалоговых окон, добавив к ним справа панель для отображения внешнего вида открываемых (записываемых) картинок. Можно пойти дальше и добавить таким же образом и свои элементы управления.

Приводимый ниже пример ModifDIg — усовершенствованная программа просмотра и сохранения файлов растровой графики, к которым относятся файлы форматов JPEG и BMP. Чтобы исключить метафайлы и значки (*.wmf, *.emf, *.ico), соответствующим образом настраиваются фильтры в диалогах открытия и сохранения.

Рис. 8.2. Внешний вид модифицированного компонента TSavePict

Для изменения размеров диалогового окна нужно отыскать в его состав компонентов панель picturepanei (так назвали Inprise) и увеличить ее высоту. Следует также поменять и ра ских окон. Поскольку они не являются компонентами Del] диалоговые окна являются составными частями Windows). Используются функции API GetWindowRect и SetWindowPos.

Обратите также внимание, что при загрузке используется событие Onprogress класса TGraphic. В его обработчике информации деланной работы отображается на компоненте progressBar1 картинок обработчик вызывается только в начале и конце зователь ничего не заметит. Зато при загрузке большого будет спокоен, видя, что процесс загрузки идет и машина не

 

Листинг 8.1 Исходный текст главного модуля программы ModifDig

unit mainUnit;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

ExtDIgs, StdCtrls, ComCtrls, ExtCtrls, Buttons;

type

TFonnl = class(TForm)

SavePictureDialogI: TSavePictureDialog;

OpenPictureDialogI: TOpenPictureDialog;

ScrollBoxl: TScrollBox;

Image 1: TImage;

ProgressBarl: TProgressBar;

OpenBitBtn: TBitBtn;

SaveBitBtn: TBitBtn;

procedure SavePictureDialoglTypeChange(Sender: TObject);

procedure ImagelProgress(Sender: TObject; Stage: TProgressStage;

PercentDone: Byte; RedrawNow: Boolean; const R: TRect;

const Msg: String);

procedure SavePictureDialoglClose(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure SavePictureDialoglShow(Sender: TObject);

procedure OpenBitBtnClick(Sender: TObject);

procedure SaveBitBtnClick(Sender: TObject);

private public end;

var

Formi: TFonnl;

implementation

<$R *.DFM) uses jpeg;

const DeltaH : Integer = 80;

var Quality : TJpegQualityRange;

ProgressiveEnc : Boolean;

procedure TForml.OpenBitBtnClick(Sender: TObject);

begin if OpenPictureDialogI.Execute

then Imagel.Picture.LoadFromFile

(OpenPictureDialogI.FileName);

end;

procedure TForml.SaveBitBtnClick(Sender: TObject);

var ji : TJpegImage;

begin if SavePictureDialogl.Execute then

begin

ji := TJpegImage.Create;

ji.CompressionQuality := Quality;

ji.ProgressiveEncoding := ProgressiveEnc;

ji.Assign(Imagel.Picture.Bitmap);

ji.SaveToFile(SavePictureDialogl.FileName);

j i.Free ;

end;

end;

procedure TFormI.SavePictureDialoglTypeChange(Sender: TObject);

var ParentHandle:THandle;wRect:TRect;

PicPanel,PaintPanel:TPanel;JEdit : TEdit;

Expanded : boolean;

begin

With Sender as TSavePictureDialog do

begin

PicPanel := (FindComponent('PicturePanel') as TPanel);

if not Assigned(PicPanel) then Exit;

ParentHandle:=GetParent(Handle);

PaintPanel:=(FindComponent('PaintPanel') as TPanel);

PaintPanel.Align := aINone;

Expanded := FindComponent('JLabel') о nil;

if Filterlndex >1 then begin if not Expanded then

begin

GetWindowRect(ParentHandle,WRect);

SetWindowPos(ParentHandle,0,0,0,WRect.Right-WRect.Left,

WRect.Bottom-WRect.Top+DeitaH,SWP_NOMOVE+SWP_NOZORDER);

GetWindowRect(Handle,WRect);

SetWindowPos(handle,0,0,0,WRect.Right-WRect.Left,

WRect.Bottom-WRect.Top+DeltaH,SWP_NOMOVE+SWP_NOZORDER);

Expanded:=True ;

PicPanel.Height := PicPanel.Height+DeltaH;

if FindComponent('JLabel')=nil then with TLabel.Create(Sender as TSavePictureDialog) do begin

Parent := PicPanel;

Name := 'JLabel';

Caption := 'Quality';

Left := 5;

Height := 25;

Top := PaintPanel.Top+PaintPanel.Height+5;

end;

if FindComponent('JEdit')=nil then begin JEdit := TEdit.Create(Sender as TSavePictureDialog);

with JEdit do begin Parent := PicPanel;

Name:='JEdit';

Text := '75';

Left:=50;Width := 50;

Height := 25;

Top := PaintPanel.

Top+PaintPanel.Height+5;

end;

end;

if FindComponent

('JUpDown')=nil

then with TUpDown.

Create(Sender as

TSavePictureDialog)

do

begin

Parent := PicPanel;

Name:='JUpDown';

Associate := JEdit;

Increment := 5;

Min := 1; Max := 100;

Position := 75;

end;

if FindComponent('JCheck')=

nil then with TCheckBox.

Create(Sender as

TSavePictureDialog) do

begin Name:='JChe;

Caption:^'Progressive

Encoding';

Parent:=PicPanel ;

Left: =5; Width :=

PicPanel.

Width -10;

Height:=25;

Top := PaintPanel.

Top+PaintPanel.

Height+35;

end;

end;

end

else

SavePictureDialoglClose(Sender);

end;

end;

procedure TForml.Imagel

Progress(Sender: TObject; Stage:

TprogressStage;

PercentDone: Byte; RedrawNow:

Boolean; const R: TRect;

const Msg: Strings-begin case Stage of psStarting: begin

Progressbarl.Position :- 0;

Progressbarl.Max := 10.0;

end;

psEnding: begin

Progressbarl.Position :- 0;

end;

psRunning:

begin

Progressbarl.Position := PercentDone;

end;

end;

end;

procedure TForml.SavePictureDialoglClose(Sender: TObject);

var PicPanel : TPanel; ParentHandle : THandle; WRect : TRect;

begin

With Sender as TSavePictureDialog do

begin

PicPanel := (FindComponent('PicturePanel') as TPanel);

if not Assigned(PicPanel) then Exit;

ParentHandle:=GetParent(Handle);

if ParentHandle=0 then Exit;

if FindComponent('JLabel')<>nil then begin FindComponent('JLabel').Free;

FindComponent('JEdit').Free;

ProgressiveEnc := (FindComponent('JCheck') as TCheckBox).Checked;

FindComponent('JCheck').Freer; Quality := (FindComponent('JUpDown') as TUpDown).Position;

FindComponent('JUpDown').Free;

PicPanel.Height:=PicPanel.Height-DeltaH;

GetWindowRect(Handle,WRect);

SetWindowPos(Handle,0,0,0,WRect.Right-WRect.Left, WRect.Bottom WRect.Top-DeltaH,SWP_NOMOVE+SWP_NOZORDER);

GetWindowRect(ParentHandle,WRect);

SetWindowPos(ParentHandle,0,0,0,WRect.Right-WRect.Left, WRect.Bottom-WRect.Top-DeltaH,SWP_NOMOVE+SWP_NOZORDER);

Filterlndex := 1;

end;

end;

end;

procedure TForml. FomCreate (Sender: TObject);

var 3: string;

begin

s :=GraphicFilter(TBitmap)+'| 4-GraphicFilter(TJpegImage);

OpenPictureDialogl.Filter := s;

SavePictureDialogI.Filter := s;

end;

procedure TForml.SavePictureDialoglShow(Sender: TObject);

begin

with Sender as TSavePictureDialog do

begin

if FindComponent('JLabel')Onil then

begin

Filterlndex := 2;

SavePictureDialoglTypeChange(Sender);

end;

end;

end;

end.

Приведенный пример может послужить толчком, во-первых, к углубленному изучению формата JPEG, а во-вторых, — к модификации стандартных диалогов. На его базе можно создать диалоги открытия аудиозаписей, документов и других специализированных видов файлов.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]