M Y D E L P H I 7 . R U Самоучитель программирования  
 
  • Главная
  •  

     

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