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

Графический формат JPEG. Класс TJPEGImage.

В 1988 году был принят первый международный стандарт сжатия неподвижных изображений. Он был назван по имени группы, которая над ним работала – JPEG (Joint Photographic Expert Group). Дело в том, что стандартные архиваторы (ZIP, ARJ) и традиционные алгоритмы сжатия в форматах GIF, TIFF и PCX не могут достаточно сильно сжать полутоновую или цветную картинку (типа фотографии) – максимум в 2-3 раза.

Примененный в JPEG алгоритм позволяет достичь сжатия в десятки раз – правда, при этом изображение подвергается необратимому искажению, и из него пропадает часть деталей. Бессмысленно (и вредно!) подвергать хранению в формате JPEG чертежи, рисунки, а также любые изображения с малым числом градаций – он предназначен именно для изображений фотографического качества.

Поддержка формата JPEG реализована в Delphi посредством класса TJPEGImage, который является потомком класса TGraphic.

Примечание
Название TJPEGImage не совсем удачное. К Timage этот класс не имеет ни малейшего отношения. Скорее, это "двоюродный брат" класса TBitmap
.

К такому объекту предъявляются двоякие требования. С одной стороны, он должен поддерживать сжатие данных для записи на диск. С другой – распакованные данные в формате DIB, чтобы по требованию системы отрисовать их. Поэтому объект класса TJPEGimage может хранить оба вида данных, а также производить их взаимные преобразования, т. е. сжатие и распаковку. Для этого в нем предусмотрены методы:

procedure Compress;
procedure DIBNeeded;
procedure JPEGNeeded;

Рекомендуется вызывать метод DIBNeeded заранее, перед отрисовкой картинки – это ускорит процесс ее вывода на экран.

Кроме того, полезно использовать метод Assign, который позволяет поместить в класс TJPEGimage объект TBitmap и наоборот:

MyJPEGImage.Assign(MyBitmap);
MyBitmap.Assign(MyJPEGImage);

При этом происходит преобразование форматов.

Свойства TJPEGimage можно условно разделить на две группы: используемые при сжатии и при распаковке.

Важнейшим из свойств, нужных при сжатии, является compressionQuality:

type TJPEGQualityRange = 1..100;
property CompressionQuaiity: TJPEGQualityRange;

Оно определяет качество сжимаемого изображения и его размер. При малых значениях этого свойства файлы получаются очень маленькими, но с большими искажениями (напомним, что стандарт JPEG предусматривает сжатие с потерями качества). При значениях, близких к 100, потери незаметны, но и размер файла при этом максимален.

Примечание
Заранее предсказать размер сжатого файла нельзя – разные картинки сжимаются по-разному, даже при одном значении CompressionQuality
.

По умолчанию значение этого свойства равно 75, что обеспечивает разумный компромисс между размером и качеством.

Кроме CompressionQuality, на качество отображения может повлиять и свойство:

type TJPEGPerformance = (jpBestQuality, jpBestSpeed);
property Performance: TJPEGPerformance;

Оно нужно только при распаковке и отвечает за способ восстановления цветовой палитры из сжатой информации. На качество записываемого изображения оно никак не влияет.

Как и у класса TBitmap, у TJPEGimage есть свойство:

type TJPEGPixelFormat = (jf24Bit, jfSBit);
property PixelFormat: TJPEGPixelForm;

Для рассматриваемого объекта возможных значений всего два – jf8bit и jf24bit. По умолчанию используется 24-битный формат. Если информация о цвете не нужна, то можно установить свойство Grayscale в значение True – в этом случае изображение будет записано (или распаковано) в полутоновом виде (256 оттенков серого).

Свойства ProgressiveEncoding и ProgressiveDisplay определяют способ показа изображения при распаковке. Первое из них отвечает за порядок записи в файл сжатых компонентов. Если ProgressiveEncoding установлено в значение True, начинает играть роль свойство ProgressiveDisplay. От его значения зависит, будет ли показываться изображение по мере распаковки (при значении True), либо будет сначала полностью распаковано, а потом показано (при значении False).

Чтобы организовать предварительный просмотр большого числа больших изображений, уместно воспользоваться свойством:

type TJPEGScale = (jsFullSize, jsHalf, jsQuarter, jsEighth);
property Scale: TJPEGScale;

Искушенные в графике специалисты зададут вопрос: зачем оно? Ведь можно прочитать изображение, а затем уменьшить его масштаб стандартными способами? Представление информации в файлах JPEG таково, что можно достаточно просто извлечь изображение сразу в нужном масштабе. Таким образом достигается двойной выигрыш – на времени распаковки и на времени отображения.

Примечание
Печать растровых изображений может вызвать проблемы при согласовании его размеров с размерами листа принтера и его разрешением. Большую часть из них можно снять, изучив пример, поставляемый с Delphi – jpegProj. Он находится не в папке \Demos, как обычно, а в папке Help\Examples\Jpeg
.

В заключение отметим, что класс TJPEGimage не имеет своей канвы для рисования – для этого его нужно преобразовать в классе TBitmap.

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