Класс TPicture
Это класс-надстройка над TGraphic, точнее — над его потомками. Он имеет поле Graphic, которое может содержать объекты классов TBitmap, Ticon, TMetafile и TJPEGimage. Предназначение класса TPicture — управлять вызовами соответствующих методов, скрывая при этом хлопоты с определением типа графического объекта и детали его реализации.
Кроме того, на уровне TPicture определены возможности регистрации и использования других — определенных пользователем — классов графических объектов, порожденных от TGraphic. Доступ к графическому объекту осуществляется посредством свойства:
property Graphic: TGraphic;
Если графический объект имеет один из трех предопределенных типов, то к нему можно обратиться и как к одному из свойств:
property Bitmap: TBitmap; property Icon: Ticon;
property Metafile: TMetafile;
Обращаясь к этим функциям, нужно быть осторожным. Если в поле Graphic хранился объект одного класса, а затребован объект другого класса, то прежний объект уничтожается, а вместо него создается пустой объект требуемого класса. Например:
Imagel.Picture.LoadFromFile('myicon.ico'); //Создан и загружен объект
класса Ticon
MyBitmap := Imagel.Picture.Bitmap; // прежний Ticon уничтожается
Если же вы описали свой класс (допустим, TGiFimage), то к его методам и свойствам следует обращаться так:
(Graphic as TGIFImage).MyProperty := MyValue;
Перечислим остальные методы и свойства.
- procedure LoadFromFile(const Filename: string);
Анализирует расширение имени файла FileName и если оно известно (зарегистрировано), то создается объект нужного класса и вызывается его метод LoadFromFile. В противном случае возникает исключительная ситуация EinvaiidGraphic. Стандартными расширениями являются ico, wmf (emf) и bmp. Если подключить к приложению модуль JPEG.PAS, то можно будет загрузить и файлы с расширениями jpg и jpeg.
- procedure SaveToFile(const Filename: string);
Сохраняет графику в файле, вызывая соответствующий метод объекта Graphic.
- procedure LoadFromClipboardFormat(AFormat: Word; AData: THandle; APalette: HPALETTE);
- procedure SaveToClipboardFormat(var AFormat: Word; var AData: THandle; var APalette: HPALETTE);
- procedure Assign(Source: TPersistent);
- class function SupportsClipboardFormat(AFormat: Word): Boolean;
- class procedure RegisterFileFormat(const AExtension, ADescription: string; AGraphicClass: TGraphicClass); class procedure RegisterClipboardFormat(AFormat: Word; AGraphicClass: TGraphicClass);
- property Width: Integer; property Height: Integer;
Все три разновидности графических объектов имеют свои системы кэширования. Это означает, что на один реально существующий в системе (и занимающий долю ресурсов!) дескриптор могут одновременно ссылаться несколько объектов. Реализуется такое связывание через метод Assign. Выражение:
Iconl.Assign(Icon2) ;
означает, что два этих объекта разделяют теперь один, фактически находящийся в памяти, значок.
Более простым является кэширование для классов TIсоn и TMetafile, которые умеют только отображать себя и не предназначены для редактирования (создатели Delphi считают, что дескриптор графического объекта дается программисту не для того, чтобы "ковыряться" в нем на уровне двоичных кодов). Гораздо сложнее устроен механизм кэширования для канала TBitmap, который имеет свою канву для рисования.
Внутреннее представление информации в графических объектах двоякое — она может храниться как поток типа TMemoryStream (в него загружается содержимое соответствующего файла), как область памяти с дескриптором (структура которой зависит от типа графического объекта) и одновременно в двух этих видах, содержимое которых автоматически синхронизируется. Поэтому будьте готовы, что загрузка изображения потребует вдвое большего объема памяти — особенно это актуально для больших картинок.
Кого-то может удивить отсутствие объявленных методов рисования, вроде метода Draw для классов Ticon, TMetafile и TBitmap. Объяснение простое — в процессе рисования они играют пассивную роль; рисуют не они — рисуют их. Все рисование должно осуществляться через вызовы методов Draw и stretchDraw канвы, содержащей графику, ибо канва соответствует тому контексту, в котором должна осуществляться операция.
Рассмотрим предопределенные графические классы.