Иллюстрированный самоучитель по Delphi 7 для профессионалов

Вывод графики с использованием отображаемых файлов

Спору нет – объект TBitmap удобен и универсален. Программисты Borland шагают в ногу с разработчиками графического API Windows, и исходный код модуля GRAPHICS.PAS от версии к версии совершенствуется. Но в ряде случаев возможностей, предоставляемых стандартным компонентом, недостаточно. Один из таких случаев – работа с большими и очень большими изображениями (до сотен Мбайт). С ними приходится иметь дело в полиграфии, медицине, при обработке изображений дистанционного зондирования Земли из космоса и т. п. Здесь класс TBitmap не подходит, т. к. запрашивает для хранения и преобразования картинки слишком много ресурсов.

Что делать? На помощь следует призвать Windows API, поддерживающий файлы, отображаемые в память (Memory Mapped Files). У них много полезных свойств, но здесь важно только одно из них. При создании битовой карты Windows распределяет для нее часть виртуального адресного пространства. А оно не безгранично – для выделения 50-100 Мбайт может не хватить размеров файла подкачки, не говоря уже об ОЗУ. Но можно напрямую отобразить файл в виртуальную память, сделав его частью виртуального адресного пространства. В этом случае нашему файлу с изображением будет просто выделен диапазон адресов, которые можно использовать для последующей работы.

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

Var Memory: pByteArray;
ес: Integer;
procedure TForml.OpenlClick(Sender: TObject);
var
i: integer;
bmFile: pBitmapFileHeader;
bmlnfo: pBitmapInfoHeader;
begin if not OpenDialogl.execute then Exit;
hf: = CreateFile(pChar(OpenDialogl.FileName), GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); if hf=INVALID_HANDLE_VALUE then
begin
ec: = GetLastError;
ShowMessage(' File opening error Ч-IntTostr (ec)); Exit;
end;
hm: = CreateFileMapping(hf,' nil, PAGE_READONLY, 0.0,nil);
if hm=0 then
begin
ShowMessage(' File Mapping error %d',[GetLastError]);
Expend;
pb: = MapViewOfFile(hm, FILE_MAP_READ, 0.0.0);
if pb=nil then
begin
ec: = GetLastError;
ShowMessage('Mapping error '+IntTostr(ec)); Exit;
end;
bmFile: = pBitmapFileHeader(pb);
if (bmFile".bfTypeO$4D42) then BEGIN
Exit;
end;
Memory: = @(рb^[bmFile^.bfOffBits]);
bmlnfo: = @(рb^[SizeOf(TBitmapFileHeader)]);
StrLen: = (((bmInfo~.biWidth*bmInfoA.biBitCount)
+31) div 32}*4;
PaintMe(Self);
end;

В этом коде последовательно получены дескрипторы файла (hf, с использованием функции CreateFile), его отображения в память (hm, с помощью функции CreateFileMapping) и указатель на отображенные данные (pb, посредством MapviewOfFile). He будем вдаваться в детали внутренней реализации битовой карты – графический формат BMP известен достаточно хорошо. Отметим только, что результатом проделанных операций являются структура bminfo типа TBitmapinfo, полностью характеризующая битовую карту, и указатель Memory на данные битовой карты.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.