logo
Программирование в среде Delphy / Программирование в среде Delphi

21.4. Работа с изображениями

Класс TCanvas, который является основой графической системы Delphi, не содержит методов сохранения отрисованных изображений. Методы сохранения картинок имеют классы: TPicture, TGraphic и TBitMap. Поэтому сохранение изображений из класса TCanvas можно осуществлять, используя один из указанных выше классов. Приведем пример сохранения картинки из класса TCanvas объекта PaintBox1 в файл с помощью методов класса TBitMap:

psSolid

psDash

psDot

psDashDot

psDashDotDot

psClear

psInsideFrame

BsSolid BsCross

BsClear BsDiagCross

BsBDiagonal BsHorizontal

BsFDiagonal BsVertical

Var Bm:TBitMap; // Определяем указатель на растровую картинку

R:TRec; // Выделяем память под прямоугольник

Begin

Bm:=TBitMap.Create; // Выделяем память под растровую картинку

R:=PaintBox1. ClientRect; // Запоминаем размеры картинки

Bm.Width:=R.Right-R.Left+1; // Передаем эти размеры объекту Bm

Bm.Height:=R.Bottom-R.Left+1;

Bm.Canvas.CopyRect(R,PaintBox1.Canvas,R); // Копируем картинку в Bm

Bm.SaveToFile(’c:\my\pic1.bmp’); // Сохраняем картинку в файле

Bm.Free; // Освобождаем память выделенную объекту Bm

Операционная система Windows поддерживает только растровые картинки и файлы с расширением *.bmp. В этих файлах первые 14 байт определяют заголовок файла, следующие 40 байт – заголовок картинки (ширина, высота, разрешение по координатам для печати картинки, число цветовых плоскостей, число цветов в палитре, метод сжатия и т.д.).

Затем идет цветовая палитра, где каждый цвет имеет свой номер и занимает в палитре 4 байта. Далее идет само растровое изображение – построчное перечисление номеров цветов для каждого пикселя (точки на экране), причем строки растра идут снизу вверх и длина каждой строки кратна 4 байтам.

Система Delphi позволяет работать и с картинками в формате JPEG (расширения файлов *.jpg). Для этого в Delphi используется специальный модуль Jpeg. В этом формате вся картинка сначала разбивается на квадратики 8*8 или 16*16 пикселей. Исходная растровая картинка каждого квадратика преобразуется, как в телевидении, в яркостную и две цветоразностные плоскости. Каждая из плоскостей подвергается дискретному, двухмерному, быстрому преобразованию Фурье. В результате этого преобразования получаются матрицы коэффициентов Фурье. В этих матрицах отбрасываются высшие составляющие коэффициентов Фурье. Оставшиеся коэффициенты матриц затем сжимаются по методу Хаффмана Число этих коэффициентов определяется параметром качества изображения. Этот формат позволяет сжимать растровые изображения в 5–20 раз в зависимости от структуры картинки, и он используется в основном для хранения фотографий людей, природы и т.д. Он также стал основой для цифрового телевидения и является основой формата MJPEG. Следует помнить, что этот формат хранит картинки с частичной потерей информации, которую человеческий глаз почти не замечает. В нем не следуетхранить, например, графики функций, изображения с резким переходом яркости или цветности, так как вокруг линий будет появляться вуаль в виде отдельных точек, что становится уже заметным нашему глазу.

Приведем пример вывода в компонент Image1 картинки из файла с расширением *.jpg. В обработчике любого события можно записать:

Var AJpeg:TJpegImage; // Определяем указатель на картинку

Begin

AJpeg:=TJpegImage.Create; // Выделяем память под картинку

AJpeg.LoadFromFile(’C:\my\pic1.jpg’); // Читаем файл

Image1.Picture:=TPicture(AJpeg); // Отображаем картинку

AJpeg.Free; // Освобождаем память из–под картинки

End;

Рассмотрим теперь пример чтения картинки из базы данных. Пусть, например, в таблице ADOTable1 есть поле Pic, в котором хранятся картинки в формате JPEG. Тогда в обработчике какого–то события можно написать.

Var AJpeg:TJpegImage; // Определяем указатель на картинку

ABlobStream:TBlobStream; // Определяем указатель на поток байт

Begin

ABlobStream:=TBlobStream.Create(ADOTable1.FieldByName (‘Pic’)

as TBlobField, bmWrite); // Связываем поле таблицы с потоком

AJpeg:=TJpegImage.Create; // Выделяем память под картинку

AJpeg.LoadFromStream(ABlobStream); // Загружаем картинку

Imag1.Picture:=TPicture(AJpeg); // Отображаем картинку

AJpeg.Free. // Освобождаем память из–под картинки

End;

Отметим так же, что в Delphi можно работать и с картинками в формате GIF, в котором картинки хранятся в сжатом виде с использованием стандартного алгоритма LZW (Лемпела–Зива–Воотча). Этот алгоритм в процессе сжатия информации создает словарь слов и запоминает не сами слова, а их коды, которые занимают памяти существенно меньше, чем слова из словаря. Все современные архиваторы данных (ARJ, ZIP, RAR и др.) используют именно этот алгоритм сжатия информации, причем процесс сжатия идет без потери информации, как это наблюдается в картинках JPEG . Этот алгоритм может сжимать изображения в 2–5 раз. Формат GIF позволяет хранить сразу несколько картинок и чередовать их появление на экране, создавая подобие мультфильма. Этот формат картинок широко используется на страничках Интернета, в нем лучше всего хранить графики функций и контрастные изображения. Он официально не поддерживается в Delphi, но есть бесплатно рассылаемая библиотека компонентов RxLib, в которой есть поддержка такого формата картинок.