![]() |
Модераторы: Snowy, Alexeis, MetalFan |
![]() ![]() ![]() |
|
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
Давно хотел сам разборраться в этом. Что же это такое на самом деле. Накопил порядка 5-6 источников и попробовал их обобщить.
Хотелось конечно уйти от сложного языка на котором пишут документацию, но повсему вижу, что не совсем получилось. html версии пока нет, как нибуь потом выложу. Во второй части попробую опиать как это все читается, там же будут примеры. В общем вот первая ее теоретическая часть. ------------------------------------------------------------------------------------------ Эта статья про то, что собой представляет графический формат BMP. Хоть это и один из простых форматов, но из-за того, что существует много вариаций этого формата, то не все моменты очевидны. Введение Формат BMP (от слов BitMaP - битовая карта, или, говоря по-русски, битовый массив) является одной из форм представления растровой графики. Проще говоря, изображение представляется в виде матрицы прямоугольных точек, где каждая точка характеризуется тремя параметрами - x координатой, y координатой и цветом. Формат BMP разрабатывался изначально двумя корпорациями Intel и Microsoft, и в то время был одинаков для обеих операционных систем Intel OS/2 Warp и Microsoft Windows 2.x. Однако далее фирма Microsoft расширила формат, расширив структуры (при этом сохранив как обратную, так и прямую совместимость для несжатых разновидностей) и добавив поддержку компрессии. Добавилась поддержка сжатия без потерь PNG и RLE, а также сжатие с потерями JPEG. Казалось бы, JPEG и BMP, совместили несовместимое, однако это только на первый взгляд. На самом деле формат BMP - является родным не только для операционных систем Windows и OS/2, но и для различных аппаратных устройств (имеется ввиду его аппаратная версия DDB - будет описана далее). Родным в том смысле, что все операции графического ввода - вывода на экран (принтер и на некоторые другие устройства) в конечном итоге осуществляются посредством него (в том или ином его виде). Так вот, поскольку современные принтеры поддерживают прямой вывод изображений в форматах PNG и JPEG на устройство, и была введена их поддержка. Тем самым, обеспечив аппаратный вывод в рамках единого формата. Под вывод BitMaP-в, оптимизируется архитектура большинства видеоадаптеров. Для чтения и вывода в ОС Windows, предусмотрено много специальных функций и структур API (библиотека gdi32.dll и gdiplus.dll), которые помогают производить все необходимые операции на достаточно высоком логическом уровне. Delphi - еще более упрощает работу предоставляя нам класс надстройку над API - TBitMap, который здесь рассматриваться не будет поскольку хорошо описан во многих источниках. В заключение к разделу хочется развеять одну неопределенность. Windows поддерживает работу с тремя битмапоподобными форматами *.bmp, *.rle, *.dib. *.rle - это сжатый битмап (как это следует из названия в формате RLE), полностью совместимый с bmp. *.dib - битмап версий Windows более чем 3.0. *.bmp - изначально предполагался быть совместимым с Windows 2.x, в последствии вероятно от этого отказались и сделали его мультиформатным. Данные форматы внутренне ни чем не друг от друга не отличаются (т.е. являются, по сути, псевдонимами *.bmp) и были введены для явного указания формата сжатия. Осознали значимость этого формата J, теперь приступим к делу. Аппаратно-зависимые и аппаратно-независимые битовые карты (Device-Dependenent and Device-Independent bitmap - DDB и DIB) Аппаратно-зависимые или DDB битмапы используются windows для хранения изображений в памяти различных графических устройств (в частности в видеопамяти). Фактически такой битмап представляет собой урезанную версию аппаратно-независимого. Его данные формируются таким образом, чтобы соответствовать конкретному графическому режиму, кроме того, такой битмап содержит упрощенный заголовок. Например, для старого 16 цветного EGA/VGA видеоадаптера, такой битмап будет представлять собой 3 цветовые матрицы (для каждого из цветов), аппаратно-независимый битмап будет содержать всего одну матрицу разрядностью 4бита на пиксель. Поскольку структура DDB битмапа меняется в зависимости от устройства к устройству, то он, как правило, создается прямо в памяти и не сохраняется в файл. Для сохранения в файл DDB конвертируется в DIB (т.е. аппаратно-независимый). В настоящее время графические ускорители оптимизируются под работу с DIB - универсальность в ущерб производительности (на самом деле эти потери незначительны). DDB битмап далее не будет описываться. Часто в литературе говорят битмап а подразумевают DIB (и наоборот) это не является грубой ошибкой. Структура формата Перед описанием структуры уточню, что структура битмапа в оперативной памяти повторяет файловую структуру, и все что верно для файла верно и для его образа в памяти, но неверно для DDB. Все структуры (записи) взяты из windows.pas с измененными именами, константы взяты из заголовочных файлов Borland C++ windows.h, wingdi.h. Файл всегда состоит из трех частей. 1) Файловый заголовок - всегда структура TBitMapFileHeader - это единственная общая структура для всех типов и версии. 2) Затем для Windows версии 2.x и OS/2 идет структура (запись) TBitmapCoreInfo. Для всех остальных версий это TBitmapInfo 3) Массив данных - структура которого весьма разнообразна. Теперь подробнее о каждой. В начале стоит заголовок файла (TBitMapFileHeader). Он описан следующим образом: TBitMapFileHeader = packed record bfType: Word; bfSize: DWORD; bfReserved1: Word; bfReserved2: Word; bfOffBits: DWORD; end; bfType - два символа определяющие тип файла. Могут быть следующие варианты: 'BM' - Windows 3.1x, 95, NT, … 'BA' - OS/2 Bitmap Array, Windows 2.x 'CI' - OS/2 Color Icon 'CP' - OS/2 Color Pointer 'IC' - OS/2 Icon 'PT' - OS/2 Pointer Программисты Windows - вероятно встречали только 'BM' (от слова BitMap, как вы уже, наверное, догадались). Не смотря на это, я полагаю, будет не лишним проверять, что за битмап нам передали (чтоб потом “не радовать” пользователя неожиданными ошибками при чтении правильных, с точки зрения, формата битмапов). bfSize - это размер самого файла в байтах. В идеале все программы для того, чтобы убедиться, что перед ними действительно правильный bmp, должны, проверить, что bfType содержит "BM" (без кавычек), а, во-вторых, что bfSize равен действительному размеру файла. Хотя далеко не все программы используют это значение, оно должно быть верным, так как - это позволит нам убедиться в том, что файл был скопирован (или скачен) целиком. bfReserved1 и bfReserved2 зарезервированы и должны быть нулями. Эти значение тоже желательно проверить, ведь в будущем они могут быть использованы для расширения формата. Естественно, что ваша программа не сможет их (такие файлы) прочитать, поэтому, узнав о ненулевых значениях можно правильно проинформировать пользователя, тем самым сэкономить его время. bfOffBits - это один из самых важных полей в этой структуре. Он показывает, где начинается сам битовый массив относительно начала файла, который и описывает картинку. Несмотря на то, что это значение можно определить по концу таблицы цветов, рекомендуется использовать именно это значение, для совместимости с возможными новыми вариациями формата. Для Windows версии 2.x и OS/2 идет структура (запись) TBitmapCoreInfo TBitmapCoreInfo = record bmciHeader: TBitmapCoreHeader; bmciColors: array[0..0 of TRGBTriple; Reserved : array[0..0 of Char; End; Где TBitmapCoreHeader = packed record bcSize : DWORD; bcWidth : Word; bcHeight : Word; bcPlanes : Word; bcBitCount: Word; end а bmciColors - цветовая палитра в формате TRGBTRiple = packed record rgbtBlue : Byte; rgbtGreen: Byte; rgbtRed : Byte; end array0..0 - не следует понимать буквально, просто количество цветов может быть различным Размер заголовка TBitmapCoreHeader хранится вbcSize и для OS/2 1.x совпадает с приведенным выше и равен 12 байтам - $0Ch. Для OS/2 2.x он занимает 15 байт? (вероятно в источнике ошибка - там указано 240 байт т.е. $F0h, вероятно имелось ввиду $0Fh - поскольку данная структура не содержит ни таблицы цветов, ни самих данных). В Windows 3.x, 95, NT возможны две версии измененной TBitmapCoreHeader. Первая TBitmapInfoHeader структура занимает 40 байт - $28h, вторая TBitmapV4Header - занимает 108 байт - $6Ch (будут описаны ниже). И, наконец, для Windows 98/Me, Windows 2000/XP - это TBitmapV5Header размером 124 байта - $7Сh (также будет описана ниже). Все размеры я указал не ради порядка, а для правильной идентификации версии, поскольку форматом не предусмотрено ни одного поля идентифицирующего версию. Чтоб не напугать новичков обилием версий замечу, что для чтения подавляющего большинства битмапов достаточно знать и использовать один лишь TBitmapInfoHeader, при этом все современные приложения правильно и корректно будут производить с ним все допустимые операции. Все структуры являются расширением первой TBitmapCoreInfo - поэтому в последующих структурах будут описаны только новые поля. bcWidth и bcHeight - ширина и высота изображения в пикселях. В последующих структурах это будут уже двойные слова (из-за этого и нет полной совместимостей новых структур с TBitmapCoreHeader). Значение bcHeight (для версий Windows 3.x, 95, NT) может быть отрицательным. В этом случае модуль bcHeight определяет действительную высоту, а строки изображения читаются в обратном порядке, т.е. сверху вниз (обычно снизу вверх). Кроме того, такие изображения всегда несжатые (т.е. BI_RGB или BI_BITFIELDS). bcPlanes - задает количество плоскостей или цветовых слоев (помните я упоминал что DDB - могут иметь 3 цветовые плоскости например R G B или C M Y- связанные с особенностями графического устройства). Сохраняемая версия битмапа т.е. DIB поддерживает пока одну общую для всех цветов плоскость, разрядность цвета этой плоскости задается bcBitCount. Попытки установить значения отличные от единицы вызывают ошибку при передаче структуры api функциям. bcBitCount - определяет разрядность цвета. Допустимы следующие варианты 0 - изображение только PNG и BMP допустимо только версии Windows 98/Me, Windows 2000/XP 1 - монохромное изображение (поддерживается всеми версиями). Каждый пиксель представлен одним битом данных, т.е. один байт содержит информацию о цвете 8 последовательно идущих пикселей. Цвет первого пикселя определяется состоянием старшего бита первого байта (и так далее), если его значение равно единице, то цвет пикселя будет определяться первой записью таблицы цветов (считается от нуля). Вообще значение цвета определяется по RGB (для BI_RGB версии) составляющим, таблицы цветов, по индексу. 4 - 16-ти цветное изображение. Каждый пиксель представлен 4 битами (поддерживается всеми версиями). 8 - изображения с количеством цветов до 256. 1 байт - 1 пиксель (поддерживается всеми версиями) 16 - поддерживается не менее чем Windows 95, и является достаточно редким. Количество цветов зависит от версии Windows и выбранного формата сжатия и может быть как 2 в 16 либо 2 в 15 степени. Это самый запутанный вариант. Начнем с того, что он беспалитровый, то есть каждые два байта (одно слово WORD) в растре однозначно определяют один пиксель. Но вот что получается: битов-то 16, а компонентов цветов - 3 (Красный, Зеленый, Синий). А 16 никак на 3 делиться не хочет. Поэтому здесь есть две варианта. Первый - использовать не 16, а 15 битов, тогда на каждую компоненту цвета выходит по 5 бит. Таким образом, мы можем использовать максимум 2 в 15 = 32768 цветов, и получается тройка R-G-B = 5-5-5. Но тогда за зря теряется целый бит из 16. Но так уж случилось, что наши глаза среди всех цветов лучше воспринимают зеленый цвет, поэтому и решили этот один бит отдавать на зеленую компоненту, то есть тогда получается тройка R-G-B = 5-6-5, и теперь мы может использовать 2 в 16 = 65536 цветов. Но что самое неприятное, что используют оба варианта. В MSDN предлагают для того, чтобы различать, сколько же цветов используется, заполнять этим значением поле biClrUsed (будет описано ниже) из структуры BITMAPINFOHEADER. Чтобы выделить каждую компоненту надо использовать следующие маски. Для формата 5-5-5: $001Fh для синей компоненты, $03E0h для зеленой и $7C00h для красной. Для формата 5-6-5: $001Fh - синяя, $07E0h - зеленая и $F800h красная компоненты соответственно. 24 - а это самый простой формат. Количество цветов 2 в 24 степени. Здесь 3 байта определяют 3 компоненты цвета. То есть по компоненте на байт. Просто читаем по структуре RGBTRIPLE(для Windows версии 2.x и OS/2) и используем его поляrgbtBlue, rgbtGreen, rgbtRed. Они идут именно в таком порядке (поддерживается всеми версиями). 32 - Здесь 4 байта определяют 3 компоненты, т.е. по-прежнему количество цветов 2 в 24 степени. Но, правда, один байт не используется. Его можно отдать, например, для альфа-канала (прозрачности). Поддерживается не менее чем Windows 95. На этом описание структур совместимых с Windows версии 2.x и OS/2 заканчиваем и переходим к современным. Это сообщение отредактировал(а) Alexeis - 10.5.2007, 18:18 -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
В Windows 3.x и старше на замену TBitmapCoreInfo приходит структура TBitMapInfo описанная следующим образом
TBitMapInfo = packed record bmiHeader : TBitmapInfoHeader; bmiColors : array[0..0 of TRGBQuad; end; Как вы, вероятно, заметили, на смену TBitmapCoreHeader пришел TBitmapInfoHeader, или его совместимые расширенные версии TBitmapV4Header и TBitmapV5Header. TBitmapInfoHeader = packed record biSize : DWORD; biWidth : Longint; biHeight : Longint; biplanes : Word; biBitCount : Word; biCompression : DWORD; biSizeImage : DWORD; biXPelsPerMeter : Longint; biYPelsPerMeter : Longint; biClrUsed : DWORD; biClrImportant : DWORD; end; //--вспомогательная структура TCIEXYZTriple = packed record ciexyzRed : TCIEXYZ; ciexyzGreen : TCIEXYZ; ciexyzBlue : TCIEXYZ; end; TBitmapV4Header = packed record bV4Size : DWORD; bV4Width : Longint; bV4Height : Longint; bV4Planes : Word; bV4BitCount : Word; bV4V4Compression : DWORD; bV4SizeImage : DWORD; bV4XPelsPerMeter : Longint; bV4YPelsPerMeter : Longint; bV4ClrUsed : DWORD; bV4ClrImportant : DWORD; bV4RedMask : DWORD; bV4GreenMask : DWORD; bV4BlueMask : DWORD; bV4AlphaMask : DWORD; bV4CSType : DWORD; bV4Endpoints : TCIEXYZTriple; bV4GammaRed : DWORD; bV4GammaGreen : DWORD; bV4GammaBlue : DWORD; end; TBitmapV5Header = packed record bV5Size : DWORD; bV5Width : Longint; bV5Height : Longint; bV5Planes : Word; bV5BitCount : Word; bV5Compression : DWORD; bV5SizeImage : DWORD; bV5XPelsPerMeter : Longint; bV5YPelsPerMeter : Longint; bV5ClrUsed : DWORD; bV5ClrImportant : DWORD; bV5RedMask : DWORD; bV5GreenMask : DWORD; bV5BlueMask : DWORD; bV5AlphaMask : DWORD; bV5CSType : DWORD; bV5Endpoints : TCIEXYZTriple; bV5GammaRed : DWORD; bV5GammaGreen : DWORD; bV5GammaBlue : DWORD; bV5Intent : DWORD; bV5ProfileData : DWORD; bV5ProfileSize : DWORD; bV5Reserved : DWORD; end; Цветовая палитра (если имеется) состоит из четырех полей, причем ее структура не зависит от разрядности цвета. TRGBQuad = packed record rgbBlue : Byte; rgbGreen : Byte; rgbRed : Byte; rgbReserved : Byte; end; Теперь рассмотрим все новые поля (тех, что не было в TBitmapCoreHeader) по очереди. biCompression - тип сжатия. О сжатии уже упоминал ранее, теперь рассмотрим его более подробно. Как вы знаете сжатие позволяет уменьшить размер изображения. Однако формат bmp создавался как несжатый и до сих пор сжатие в bmp встречается крайне редко. Здесь возможны 6 вариантов: Const BI_RGB = $00000000; BI_RLE8 = $00000001; BI_RLE4 = $00000002; BI_BITFIELDS = $00000003; BI_JPEG = $00000004; BI_PNG = $00000005; Из них BI_RGB и BI_BITFIELDS являются несжатыми. Вопрос сжатых битмапов слишком сложный чтоб рассмотреть его в рамках этой статьи, поэтому подробно рассмотрен не будет. Ручная распаковка таких форматов сложна, и мало полезна, поскольку Windows берет на себя эту задачу. Форматы сжатия BI_RLE8, BI_RLE4, BI_BITFIELDS были введены в Windows начиная с 3 версии и были дополнены BI_JPEG и BI_PNG в Windows 98/Me, Windows 2000/XP. Форматы BI_RLE8, BI_RLE4 используются для сжатия только 8-ми и 4-х бит на пиксель изображений соответственно. Формат BI_BITFIELDS - представляет собой беспалитровый формат цвета. В нем цвета задаются при помощи 3-х четырех битовых масок, идущих сразу после структуры (по маске на каждый цвет). Примеры таких масок приведены уже были в описании цвета 16 бит на пиксель. Для 32 бита на пиксель маски для синего, зеленого и красного цветов имеют вид $000000FFh, $0000FF00h, $00FF0000h соответственно. Как же можно выделить цвет при помощи такой маски, да легко! Например, пусть нужно выделить зеленый цвет из двойного слова 32 бит на пиксель. G := (Data and $0000FF00h) shr 8; или в общем B := (Data and BlueMask) shr (0 * biBitCount); G := (Data and GreenMask) shr (1 * biBitCount); G := (Data and RedMask) shr (2 * biBitCount); Такой формат можно использовать только для разрядности цвета 16 и 32 бита на пиксель. Данные представлены не индексами в палитре, а значениями цвета. Формат BI_RGB также является несжатым. Отличие от BI_BITFIELDS, состоит в том, что он поддерживает изображения с разрядностью цвета biBitCount от 1 до 32 бит на пиксель, при этом битмапы с biBitCount от 1 до 8 обязаны содержать палитру, а значения цветовых данных определяют индекс цвета в палитре, битмапы с biBitCount от 16 до 32 как правило не содержат палитры (но формат допускает присутствие палитры и в этом случае), значения цветовых данных определяют цвет пикселя (даже при наличии палитры). Подробнее см. biClrUsed. biSizeImage обозначает размер картинки в байтах. Если изображение несжатое (то есть предыдущее поле установлено в BI_RGB), то это значение не используется - рекомендовано устанавливать в ноль (но другие значения не запрещены). Для сжатых изображений (biCompression имеет значение BI_JPEG или BI_PNG) - biSizeImage определяет размер буфера данных (блока данных). biXPelsPerMeter и biYPelsPerMeter обозначают соответственно горизонтальное и вертикальное разрешение (в пикселях на метр) рекомендуемое для установки в конечном устройстве, на которое будет выводиться битовый массив. Приложение может использовать это значение для того, чтобы выбирать из группы ресурсов наиболее подходящий битовый массив для нужного устройства. Напомню, что формат bmp - это по сути аппаратно-независимый растр, то есть универсальный для всех устройств, отличительной особенностью которого является то, что картинка будет выглядеть одинаково вне зависимости от того, рисуется она на экране монитора или печатается на принтере. Но вот разрешение у устройств разное, и именно для того, чтобы выбрать наиболее подходящую картинку из имеющихся и используют эти параметры. biClrUsed определяет количество используемых цветов из таблицы. Если это значение равно нулю, то либо в растре используется максимально возможное количество цветов, которые разрешены значением biBitCount, либо изображение сжато. Если biClrUsed не нуль, а biBitCount меньше 16, то biClrUsed определяет текущее число цветов палитры. Если biBitCount больше или равно 16 (количество цветов более 256), то biClrUsed определяет размер таблицы цветов, используемой для оптимизации текущей системной палитры. Такая таблица цветов, как уже упоминалось, присутствует достаточно редко, но может привести к появлению ошибок при чтении цветового массива, если программа не использует значение bfOffBits для определения начала битового массива, а вместо этого интерпретирует байты, следующие непосредственно за TBitmapInfoHeader (или ее расширенного варианта), как начало растра. biClrImportant - это количество важных для изображения цветов. Если это значение равно 0 (как это обычно и бывает), то все цвета считаются важными. Это поле было введено поддержки устройств с малым количеством цветов. Например, если на устройстве, поддерживающем только 256 цветов, отображаются более одного изображения с числом цветов 256 с разными палитрами, то естественно, что для правильного отображения суммарной картинки потребуется общая палитра с числом цветов превышающим 256. В этом случае в общую палитру вводят вначале важные цвета (в палитре они должны идти первыми) по возможности всех изображений, затем вносят другие. Если нужного цвета в палитре не окажется, то он будет заменен, на наиболее близкий. На этом описание основных полей TBitmapInfoHeader закончено, дальше пойдет описание расширенных полей (TBitmapV4Header, TBitmapV5Header), т.е. не обязательных для чтения. Эта информация нигде, кроме как в MSDN, не дается. Это сообщение отредактировал(а) Alexeis - 10.5.2007, 18:32 -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
bV4RedMask, bV4GreenMask, bV4BlueMask, bV4AlphaMask - Маски заменяющие палитру при сжатии bV4Compression (аналог biCompression) установленном в BI_BITFIELDS - были описаны выше. bV4AlphaMask - дополнительная маска используемая при bV4BitCount равном 32 и служит для описания альфа состовляющей цвета.
bV4CSType - Определяет цветовое пространство DIB. Цветовое пространство это некоторое логическое описание цвета в виде вектора в 3-х или 4-х мерном пространстве, где каждое измерение - интенсивность одного из цветов или альфа-канала. Допустимые значения - LCS_CALIBRATED_RGB = #0#0#0#0; LCS_sRGB = 'sRGB'; LCS_WINDOWS_COLOR_SPACE = 'Win '; PROFILE_LINKED = 'LINK'; PROFILE_EMBEDDED = 'MBED'; - последние 2 варианта доступны только в пятой версии заголовка. LCS_CALIBRATED_RGB - указывает, что координаты конца вектора цвета и гамма составляющая идут в смежных полях. О гамма составляющей см. ниже. LCS_sRGB - указывает на то, что будет использоваться цветовое пространство sRGB. LCS_WINDOWS_COLOR_SPACE - указывается, что используется стандартное для Windows цветовое пространство, обычно соответствует LCS_sRGB. PROFILE_LINKED - говорит о том, что данные специальной профильной области не содержатся в изображении, хранятся в дополнительном файле имя которого хранится в bV5ProfileData. Профиль должен соответствовать ICC для интерфейса ICM 2.0. Профили были введены начиная с Windows 98, для обеспечения более точной цветопередачи. В этом режиме вектор цвета и гамма игнорируются. PROFILE_EMBEDDED - говорит о том, что данные специальной профильной области расположены в памяти указатель на которую находится в поле bV5ProfileData. Значение bV5ProfileData - обычно не определено до загрузки изображения в память. В этом режиме вектор цвета и гамма игнорируются. bV4Endpoints - структура типа TCIEXYZTriple определяющая x, y, z - координаты соответствующие трем цветам - красному, зеленому и синему для логического цветового пространства битмапа, определенного константой LCS_CALIBRATED_RGB. bV4GammaRed, bV4GammaGreen, bV4GammaBlue - параметр, характеризующий кривую отклика оттенка цвета (красного, зеленого и синего соответственно). Используется только при bV4CSType установленном в LCS_CALIBRATED_RGB. bV5Intent - тип тонирования (intent) изображения. Возможные варианты: LCS_GM_ABS_COLORIMETRIC = $00000008; LCS_GM_BUSINESS = $00000001; LCS_GM_GRAPHICS = $00000002; LCS_GM_IMAGES = $00000004; Данные параметры определяют каким образом цветовое пространство будет конвертироваться в палитру цветов. Более подробно см. Image Color Management Version 2.0 в MSDN bV5ProfileData - смещение в битмапе. Для bV5CSType установленном в PROFILE_LINKED указывает на нультерминатную строку хранящую имя файла цветового профиля. Строка может содержать полный путь к файлу профиля включая также сетевой путь. Для bV5CSType установленном в PROFILE_EMBEDDED это смещение собственно на цветовой профиль. Смещение отсчитывается от конца структуры TBitmapV5Header (данные растра не следуют сразу за таблицей цветов). Значение bV5ProfileData имеет смыл только для загруженного в память битмапа и должно быть установлено только после загрузки. Использование таких цветовых профилей допустимо только для файлов, у которых размер структуры (поле bV5Size) TBitmapInfoHeader, равно значению SizeOf(TBitmapV5Header) т.е. 124 байтам. После структуры TBitmapInfoHeader следует массив из структур TRGBQuad хранящий таблицу цветов. Такой массив может и отсутствовать в зависимости от битности данных. Каждый элемент характеризует один из используемых цветов. Четвертое поле должно быть установлено всегда в нуль. Рекомендуется записывать цвета в порядке их важности см. biClrImportant. Как уже упоминалось для 5-й версии заголовка, в памяти цветовая палитра может идти не сразу за структурой TBitmapInfoHeader а с некоторым смещением. Растр - представляет собой блок данных каждый байт, которого интерпретируется согласно формату сжатия и битности данных. Для biCompression BI_JPEG, BI_PNG структура блока не тривиальна (определяется форматом). Для BI_RLE8, BI_RLE4 этот блок разбивается на множество чередующихся подблоков различного размера, в каждом из которых хранится либо последовательность цветов с неповторяющимися значениями, либо число повторений некоторого цвета, либо маркеры конца строки или блока данных. Для BI_RGB иBI_BITFIELD это строки изображения, записанные в порядке снизу вверх (если значение высоты битмапа отрицательное, то наоборот). Каждая строка выравнивается на границу двойного слова (4 байта). Лишние младшие биты могут принимать произвольные значения, но обычно устанавливаются в нуль. Размер растра в байтах можно вычислить следующим образом: (((((((biWidth * biBitCount + 7) shr 3) + 3) shr 2) shl 2) * abs(biHeight) + 3) shr 2) shl 2. Конец первой части Это сообщение отредактировал(а) Alexeis - 14.5.2008, 16:18 -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
Наконец дописал вторую часть
Формат BMP (часть вторая) В этой части попробуем написать программу, работающую с BMP файлами. Как вы знаете, несжатые битмапы занимают на диске достаточно много места, особенно много занимают изображения в формате 24 бита на пиксель. Фотографии сжимают в jpeg. Однако такие изображения как чертежи и графики сжимать с потерями, конечно, нельзя. Очень хорошее сжатие без потерь дает формат png (в настоящее время он очень распространен). Это довольно сложный формат и в рамках этой статьи не рассматривается. Оказывается, некоторые изображения можно в несколько раз уменьшить в размерах не прибегая к другим форматам, а просто уменьшив число байт занимаемых одним пикселем. Многие, наверное, пробовали сохранять изображение True Color в формате 256 цветов – результат жуткое искажение цвета, даже если действительное число цветов не превышало 256. Дело в том, что программы типа Microsft Paint создают свою собственную палитру на 256 цветов и интерполируют исходное изображение при помощи имеющихся цветов. Метод, конечно, универсальный, но совершенным его не назовешь. Эта программа будет считать количество цветов реально использованных в изображении и если их число не более 256, то создавать новый палитровый битмап с числом цветов 2, 16, 256 – в зависимости от числа использованных цветов. Чтобы сделать программу еще более универсальной, я добавил поддержку беспалитровых изображений не только на 24 бита на пиксель, но и 16 и 32. Как показал мой печальный опыт изображения в формате 16 бит на пиксель не могут быть однозначно прочтены, поскольку программы обычно не оставляют ни каких заметок (хотя MSDN этого требует) какую схему цветов они использовали (5-5-5 или 5-6-5). По умолчанию принимается старый формат 5-5-5. Кроме того введена нестрогая проверка цветов – если хоть один цвет в палитре имеет значение, превышающее 2 в 15 степени, то такое изображение рассматривается по схеме 5-6-5. Буду очень благодарен тому, кто расскажет, как более строго можно отличить такие форматы. Код снабжен подробными комментариями, а потому дальнейшее описание думаю будет лишним. Добавлено @ 14:24 Код в один пост не поместился так что разбил на два
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
Прикрепляю и весь проект целиком Это сообщение отредактировал(а) alexeis1 - 17.5.2006, 14:32 Присоединённый файл ( Кол-во скачиваний: 221 ) ![]() -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
rz3rr |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 27.11.2005 Репутация: нет Всего: нет |
Подскажи, пожалуйста, как мне из массива (двухмерного, 1-е измерение-адрес точки, 2-е - палитра(RGB)) загрузить данные в TImage (естественно, через bitmap). Что-то никак не врублюсь.
|
|||
|
||||
rz3rr |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 27.11.2005 Репутация: нет Всего: нет |
Да, забыл уточнить. Высота и ширина "картинки" (integer) идет отдельными параметрами.
|
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
Уточните задачу
Как двумерный массив может содержать и растр и палитру? Опишите более строго ваши струкруры данных.(желательно фрагменты кода) -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
rz3rr |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 27.11.2005 Репутация: нет Всего: нет |
Не проблема преобразовать в трехмерный, типа Myarr[v,h,rgb].
На определенном этапе мне нужен был духмерный. А количество точек по вертикали и горизонтали шли отдельным параметром. |
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: нет Всего: 133 |
Эксперементы со шрифтами на пользу не пошли. Трудно читать. Исправь пожалуйста
![]() -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
Albinos_x |
|
|||
![]() Evil Skynet ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3288 Регистрация: 28.5.2004 Где: X-6120400 Y-1 4624650 Репутация: 1 Всего: 108 |
угу... наверно стандартный лучше будет... и статью наверно стоит или закрепить, или в FAQ отправить... ![]() -------------------- "Кто владеет информацией, тот владеет миром" Уинстон Черчилль |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
Poseidon, Обязательно поправлю, вот только сейчас не могу. Дело в том, что в текст писал в Microsoft Word, а в ручную переделывать очень долго, поэтому написал специальную програмку - конвертер RTF->BBCode. Т.о. основной текст написан шрифтом "Times new roman", как видно интервал получается не полуторным а одинарным. Кроме того полученый bbCode пока великоват. Как только переделаю программу, так сразу исправлю пост...
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Yanis |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2937 Регистрация: 9.2.2004 Где: Москва Репутация: 2 Всего: 111 |
alexeis1
Может закачаешь статью в виде файла? А то никак не собирусь статью прочитать. Глаза ломаются после 10 строчек ![]() |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
Появилось немного времени
Вот HTML версия ее по легче будет читать ссылка Это сообщение отредактировал(а) alexeis1 - 3.7.2006, 09:45 -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Yuriy1 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 2 Регистрация: 18.5.2008 Репутация: нет Всего: нет |
Вступление
========== Есть картинка, красного цвета, в формате "bmp", шириной 1 пиксель и высотой 1 пикселей. Чтобы Вы получили представление об этой картинке изображу эту картинку в виде буквы: К или её можно записать, условно так: FF0000 В base64 она будет выглядеть так: Qk06AAAAAAAAADYAAAAoAAAAAQAAAAEAAAABABgAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ AA== Цветная картинка, красного цвета, шириной 2 пикселя и высотой 1 пиксель. В виде букв: КК или её можно записать, условно так: FF0000 FF0000 В base64 она будет выглядеть так: Qk0+AAAAAAAAADYAAAAoAAAAAgAAAAEAAAABABgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ AAD/AAA= Цветная картинка, красного цвета, шириной 3 пикселя и высотой 1 пиксель. В виде букв: ККК или её можно записать, условно так: FF0000 FF0000 FF0000 В base64 она будет выглядеть так: Qk1CAAAAAAAAADYAAAAoAAAAAwAAAAEAAAABABgAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ AAD/AAD/AAAA Вопрос ====== Есть цветная картинка, в формате "bmp", шириной (например)3 пикселя и высотой (например) 2 пикселя. Чтобы Вы получили представление об этой картинке изображу эту картинку в виде букв: КЖЗ КЖЗ Здесь одна буква, как бы показывает один пиксель, а её название цвет этого пикселя (К-красный, Ж-Жёлтый , З-Зелёный). или её можно записать, условно так: FF0000 FFFF00 00FF00 FF0000 FFFF00 00FF00 Здесь FF0000 означает один пиксель красного цвета, FFFF00 означает один пиксель жёлтого цвета, и т.д. две строки означают 2 пикселя по высоте. Подскажите, пожалуйста, по какому алгоритму можно из записи: FF0000 FFFF00 00FF00 FF0000 FFFF00 00FF00 получить (вручную) запись этой картинки в base64: Qk1OAAAAAAAAADYAAAAoAAAAAwAAAAIAAAABABgAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ AP//AP8AAAAAAAD/AP//AP8AAAAA (формат "bmp", не принципиален, если для какого то другого формата это сделать легче, то можно и в другом) |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Звук, графика и видео" | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делится вскрытыми компонентами
FAQ раздела лежит здесь! Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |