|
Графический формат 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.
|