Формат файла bmp c
Эта статья про то, как выглядит графический формат bmp. Хоть это и один из простых форматов, но из-за того, что существует много вариаций этого формата, то не все моменты очевидны. Итак, хватит лить воду, начнем.
Структуры формата
Формат bmp (от слов BitMaP - битовая карта, или, говоря по-русски, битовый массив) представляет из себя несжатое (в основном) изображение, которое довольно легко читается и выводится в ОС Windows, в которой есть специальные функции API, которые в этом помогают.
Для начала приведем графическое представление данных в bmp (картинка взята из MSDN).
В начале стоит заголовок файла (BITMAPFILEHEADER). Он описан следующим образом:
typedef struct tagBITMAPFILEHEADER
{
WORD bfType ;
DWORD bfSize ;
WORD bfReserved1 ;
WORD bfReserved2 ;
DWORD bfOffBits ;
} BITMAPFILEHEADER, * PBITMAPFILEHEADER ;
bfType определяет тип файла. Здесь он должен быть BM. Если Вы откроете любой файл BMP в текстовом (а лучше в 16-ричном редакторе), то увидите, что первые два символа - это BM (от слова BitMap, как вы уже, наверное, догадались).
bfSize - это размер самого файла в байтах. Строго говоря вы должны его высчитывать (что рекомендуется), но я ставил размер файла неправильно (правда, не нарочно :)) и никаких проблем не было (ACDSee читало без проблем, моя программа работала), но я вам не рекомендую писать его заведомо неправильно, вдруг появится добросовестная программа, которая сверит этот размер с настоящим и решит, что это не bmp, а что-нибудь другое. В идеале все программы для того, чтобы убедиться, что перед ними действительно bmp, а не подделка, должны, во-первых, проверить, что bfType содержит "BM" (без кавычек), а, во-вторых, что bfSize равен размеру файла.
bfReserved1 и bfReserved2 зарезервированы и должны быть нулями.
bfOffBits. Это один из самых важных полей в этой структуре. Он показывает, где начинается сам битовый массив относительно начала файла (или, как написано в MSDN, "от начала структуры BITMAPFILEHEADER"), который и описывает картинку. То есть, чтобы гарантированно попадать на начало массива вы должны писать:
Здесь и далее будем считать, что переменная bfh объявлена как BITMAPFILEHEADER bfh;
А дальше идет структура BITMAPINFOHEADER, которая объявлена так:
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize ;
LONG biWidth ;
LONG biHeight ;
WORD biPlanes ;
WORD biBitCount ;
DWORD biCompression ;
DWORD biSizeImage ;
LONG biXPelsPerMeter ;
LONG biYPelsPerMeter ;
DWORD biClrUsed ;
DWORD biClrImportant ;
} BITMAPINFOHEADER, * PBITMAPINFOHEADER ;
biSize - это размер самой структуры. Ее нужно инициализировать следующим образом: bih.biSize = sizeof (BITMAPINFOHEADER);
Снова здесь и дальше будем считать, что bih объявлена следующим образом: BITMAPINFOHEADER bih;
biWidth и biHeight задают соответственно ширину и высоту картинки в пикселях.
biPlanes задает количество плоскостей. Пока оно всегда устанавливается в 1.
biBitCount - Количество бит на один пиксель. Подробнее про это поговорим ниже.
biCompression обозначает тип сжатия. Не удивляйтесь и не пугайтесь, что в bmp и вдруг сжатие. Я лично не видел не одной сжатой bmp (но я не говорю, что таких не существует). Если сжатия нет, то этот флаг надо устанавливать в BI_RGB. В этой статье мы говорим про несжатый формат, поэтому другие флаги я даже не буду перечислять. Похоже, что эта же структура используется и в файлах JPEG и PNG, потому что, начиная с Windows 98 тут появились варианты BI_JPEG, которая показывает, что эта картинка - JPEG и BI_PNG, что это PNG (про формат Jpeg я ничего не знаю, я только сделал эти выводы исходя из того, что написано в MSDN).
biSizeImage обозначает размер картинки в байтах. Если изображение несжато (то есть предыдущее поле установлено в BI_RGB), то здесь должен быть записан ноль. biXPelsPerMeter и biYPelsPerMeter обозначают соответственно горизонтальное и вертикальное разрешение (в пикселях на метр) конечного устройства, на которое будет выводиться битовый массив (растр). Приложение может использовать это значение для того, чтобы выбирать из группы ресурсов наиболее подходящий битовый массив для нужного устройства. Дело в том, что формат bmp - это по сути аппаратно-независимый растр, то есть когда внешний вид того, что получается не зависит от того, на что этот растр проецируется (если можно так выразится). Например, картинка будет выглядеть одинаково вне зависимости от того, рисуется она на экране монитора или печатается на принтере. Но вот разрешение у устройств разное, и именно для того, чтобы выбрать наиболее подходящую картинку из имеющихся и используют эти параметры.
biClrUsed определяет количество используемых цветов из таблицы. Если это значение равно нулю, то в растре используется максимально возможное количество цветов, которые разрешены значением biBitCount. Это актуально только для сжатых картинок. Если biClrUsed не нуль и biBitCount меньше 16, то biClrUsed определяет текущее число цветов графического движка или доступного драйвера устройства. Если biBitCount больше или равно 16, то biClrUsed определяет размер таблицы цветов, используемой для оптимизации текущей системной палитры.
biClrImportant - это количество важных цветов. Определяет число цветов, которые необходимы для того, чтобы изобразить рисунок. Если это значение равно 0 (как это обычно и бывает), то все цвета считаются важными.
Виды формата BMP
Все разновидности формата bmp условно можно разделить на два типа: палитровые и беспалитровые. То есть используется в данном с формате палитра или нет. Заметьте, что палитра может быть даже в беспалитровых форматах, только там она не используется. В беспалитровых bmp цвет высчитывается прямо из тех битов, которые идут в файле, начиная с некоторого места. А в палитровых каждый байт описывает один или несколько пикселей, причем значения байта (или битов) - это индекс цвета в палитре. Для начала приведу таблицу, которая сравнивает возможные варианты. Вид картинки (палитровая или беспалитровая) зависит от того, сколько бит отдается на один пиксель, то есть от значения biBitCount структуры BITMAPINFOHEADER.
biBitCount | Палитровый или беспалитровый формат | Максимально возможное количество цветов | Примечания |
1 | Палитровый | 2 | Двуцветная, заметьте, не обязательно черно-белая, палитровая картинка. Если бит растра (что это такое чуть ниже) сброшен (равен 0), то это значит, что на этом месте должен быть первый цвет из палитры, а если установлен (равен 1), то второй. |
4 | Палитровый | 16 | Каждый байт описывает 2 пикселя. Вот пример из MSDN.Если первый байт в картинке 0x1F, то он соответствует двум пикселям, цвет первого - второй цвет из палитры (потому что отсчет идет от нуля), а второй пиксель - 16-й цвет палитры. |
8 | Палитровый | 256 | Один из самых распространенных вариантов. Но в то же время и самых простых. Палитра занимает один килобайт (но на это лучше не рассчитывать). Один байт - это один цвет. Причем его значение - это номер цвета в палитре. |
16 | Беспалитровый | 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: 0x001F для синей компоненты, 0x03E0 для зеленой и 0x7C00 для красной. Для формата 5-6-5: 0x001F - синяя, 0x07E0 - зеленая и 0xF800 красная компоненты соответственно. |
24 | Беспалитровый | 2^24 | А это самый простой формат. Здесь 3 байта определяют 3 компоненты цвета. То есть по компоненте на байт. Просто читаем по структуре RGBTRIPLE и используем его поля rgbtBlue, rgbtGreen, rgbtRed. Они идут именно в таком порядке. |
32 | Беспалитровый | 2^32 | Здесь 4 байта определяют 3 компоненты. Но, правда, один байт не используется. Его можно отдать, например, для альфа-канала (прозрачности). Читать растр в данном случае удобно структурами RGBQUAD, которая описана так: |
typedef struct tagRGBQUAD
{
BYTE rgbBlue ;
BYTE rgbGreen ;
BYTE rgbRed ;
BYTE rgbReserved ;
} RGBQUAD ;
Хранение данных в формате bmp
Ну вот и подошли к самому интересному. После структур BITMAPFILEHEADER и BITMAPINFOHEADER идет палитра. Причем, если формат беспалитровый, то ее может и не быть, однако, на это рассчитывать не надо. Дело в том, что, когда я только начинал разбираться с форматом bmp, в одной книжке я вычитал, что, якобы, если формат беспалитровый, то у нее вообще нет палитры. Там даже были две картинки - схемы формата: одна с палитрой, другая без. А я в это время писал программу, которая усердно оперирует с bmp-шками. И мне надо было преобразовывать входящие картинки из 256 цветов в 24-битные (если таковые имелись) во временные файлы. И я в 24-битных палитру просто не создавал (bfOffBits из структуры BITMAPFILEHEADER у меня был равен сумме sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER), а входящие 24-разрядные оставлял без изменений. С 256-цветными растрами все работало как надо, пока мне не попалась 24-разрядная картинка, у которой внизу вместо нужной части отображался мусор. Я не сразу понял в чем дело. Пока не сравнил размер исходного файла с теоретическим, который должен был быть, не будь палитры. Разница оказалась ровно 1 Kб (ровно 1024 байта). Там была палитра. Поэтому никогда не рассчитывайте на то, есть ли палитра и не надейтесь на ее размер (хотя все картинки, которые мне попадались имели размер палитры 256 цветов, или 1Кб), всегда перемещайтесь по файлу на начало растра, используя bfOffBits. Палитра представляет из себя массив структур RGBQUAD идущих друг за другом. Даже если в палитре используются не все цвета (а только, например, 16), то часто все равно под палитру отводят 256 полей. А 256 * 4 = 1024, где 4 - размер структуры RGBQUAD, то есть и получается тот самый один килобайт.
Сразу за палитрой идет сам растр. Тут уже более запутано. Во-первых, пиксели тут описываются так, как написано в таблице выше в зависимости от формата. И могут сами содержать значение компонентов цвета (для беспалитровых), а могут быть индексами массива-палитры. Сама картинка записывается построчно. Во-вторых, картинка идет как бы перевернутая вверх ногами. То есть сначала записана нижняя строка, потом предпоследняя и так далее до самого верха. И, в-третьих, как написано в [1], если размер строки растра не кратен 4, то она дополняется от 1 до 3 пустыми (нулевыми) байтами, чтобы длина строки оказалась кратна параграфу. Вот это и есть самое неприятное. Дело в том, что для каждого формата приходится подстраивать это число пустых байтов (правда, я люблю туда записывать часть палитры, просто мне не хочется заводить лишние "нулевые" переменные, если все-равно эти байты пропускают и никому они не нужны). Я привожу таблицу с формулами, которые показывают для какого формата сколько байт надо дописывать в конец строки. Там под переменной Width, как можно догадаться, подразумевается ширина картинки. Все эти формулы были установлены экспериментально. Я приведу пример только для наиболее используемых форматов. Для остальных вы можете написать сами.
biBitCount | Формула на С |
8 | (3 * Width) % 4 |
16 | (2 * Width) % 4 |
24 | Width % 4 |
Примеры программ
Все исходники вы можете скачать отсюда.Я особо не буду тут много писать. Просто приведу функции с комментариями.
Привет 1. Создание картинки в формате bmp.
Здесь создается однотонная картинка. В примерах таких функций три: создание bmp 8, 16 и 24 бит. Я приведу только для 16-битных.
// Создадим картинку в формате bmp 16 бит типа 5-5-5, которая будет просто однотонной
void CreateBmp555 ( char * fname, WORD color )
{
HANDLE hFile ;
DWORD RW ;
int i, j ;
// Объявим нужные структуры
BITMAPFILEHEADER bfh ;
BITMAPINFOHEADER bih ;
BYTE Palette [ 1024 ] ; // Палитра
// Пусть у нас будет картинка размером 35 x 50 пикселей
int Width = 35 ;
int Height = 50 ;
memset ( Palette, 0 , 1024 ) ; // В палитре у нас нули заполним их
memset ( & bfh, 0 , sizeof ( bfh ) ) ;
bfh. bfType = 0x4D42 ; // Обозначим, что это bmp 'BM'
bfh. bfOffBits = sizeof ( bfh ) + sizeof ( bih ) + 1024 ; // Палитра занимает 1Kb, но мы его использовать не будем
bfh. bfSize = bfh. bfOffBits +
sizeof ( color ) * Width * Height +
Height * ( ( sizeof ( color ) * Width ) % 4 ) ; // Посчитаем размер конечного файла
memset ( & bih, 0 , sizeof ( bih ) ) ;
bih. biSize = sizeof ( bih ) ; // Так положено
bih. biBitCount = 16 ; // 16 бит на пиксель
bih. biClrUsed = 32768 ; // Мы используем 5-5-5
bih. biCompression = BI_RGB ; // Без сжатия
bih. biHeight = Height ;
bih. biWidth = Width ;
bih. biPlanes = 1 ; // Должно быть 1
// А остальные поля остаются 0
hFile = CreateFile ( fname, GENERIC_WRITE, 0 , NULL , CREATE_ALWAYS, 0 , NULL ) ;
if ( hFile == INVALID_HANDLE_VALUE )
return ;
// Выровняем по границе
WriteFile ( hFile, Palette, ( sizeof ( color ) * Width ) % 4 , & RW, NULL ) ;
}
CloseHandle ( hFile ) ;
}
color - цвет картинки. Значение этой переменной должно быть заполнено в соответствии с первой таблицей. Получившуюся картинку вы можете посмотреть в ACDSee, например. Просто я пробовал ее открыть в Photoshop'е, оказалось, что в этом формате он их читать не умеет. А вы можете :).
Пример 2. Преобразование картинки из формата 8 бит (256 цветов) в 24 бит.
BOOL Convert256To24 ( char * fin, char * fout )
{
BITMAPFILEHEADER bfh ;
BITMAPINFOHEADER bih ;
int Width, Height ;
RGBQUAD Palette [ 256 ] ;
BYTE * inBuf ;
RGBTRIPLE * outBuf ;
HANDLE hIn, hOut ;
DWORD RW ;
DWORD OffBits ;
int i, j ;
hIn = CreateFile ( fin, GENERIC_READ, FILE_SHARE_READ, NULL , OPEN_EXISTING, 0 , NULL ) ;
if ( hIn == INVALID_HANDLE_VALUE )
return FALSE ;
hOut = CreateFile ( fout, GENERIC_WRITE, 0 , NULL , CREATE_ALWAYS, 0 , NULL ) ;
if ( hOut == INVALID_HANDLE_VALUE )
{
CloseHandle ( hIn ) ;
return FALSE ;
}
// Прочтем данные
ReadFile ( hIn, & bfh, sizeof ( bfh ) , & RW, NULL ) ;
ReadFile ( hIn, & bih, sizeof ( bih ) , & RW, NULL ) ;
ReadFile ( hIn, Palette, 256 * sizeof ( RGBQUAD ) , & RW, NULL ) ;
// Установим указатель на начало растра
SetFilePointer ( hIn, bfh. bfOffBits , NULL , FILE_BEGIN ) ;
Width = bih. biWidth ;
Height = bih. biHeight ;
OffBits = bfh. bfOffBits ;
// Выделим память
inBuf = new BYTE [ Width ] ;
outBuf = new RGBTRIPLE [ Width ] ;
// Заполним заголовки
bfh. bfOffBits = sizeof ( bfh ) + sizeof ( bih ) ; // Не будем писать палитру
bih. biBitCount = 24 ;
bfh. bfSize = bfh. bfOffBits + 4 * Width * Height + Height * ( Width % 4 ) ; // Размер файла
// А остальное не меняется
// Запишем заголовки
WriteFile ( hOut, & bfh, sizeof ( bfh ) , & RW, NULL ) ;
WriteFile ( hOut, & bih, sizeof ( bih ) , & RW, NULL ) ;
// Начнем преобразовывать
for ( i = 0 ; i < Height ; i ++ )
{
ReadFile ( hIn, inBuf, Width, & RW, NULL ) ;
for ( j = 0 ; j < Width ; j ++ )
{
outBuf [ j ] . rgbtRed = Palette [ inBuf [ j ] ] . rgbRed ;
outBuf [ j ] . rgbtGreen = Palette [ inBuf [ j ] ] . rgbGreen ;
outBuf [ j ] . rgbtBlue = Palette [ inBuf [ j ] ] . rgbBlue ;
}
WriteFile ( hOut, outBuf, sizeof ( RGBTRIPLE ) * Width, & RW, NULL ) ;
// Пишем мусор для выравнивания
WriteFile ( hOut, Palette, Width % 4 , & RW, NULL ) ;
SetFilePointer ( hIn, ( 3 * Width ) % 4 , NULL , FILE_CURRENT ) ;
}
delete inBuf ;
delete outBuf ;
CloseHandle ( hIn ) ;
CloseHandle ( hOut ) ;
return TRUE ;
}
В функцию надо передавать имена исходного и конечного файла соответственно.
Источники
- Д. Гончаров, Т. Салихов. "DirectX 7.0 для программистов"
- MSDN
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Инкапсулирует точечный рисунок GDI+, состоящий из данных пикселей графического изображения и атрибутов рисунка. Объект Bitmap используется для работы с изображениями, определяемыми данными пикселей.
Примеры
В следующем примере кода показано, как создать новый объект Bitmap из файла, используя GetPixel методы и SetPixel методы для перекраски изображения. Он также использует PixelFormatWidthсвойства и Height свойства.
Этот пример предназначен для использования с Windows Forms, содержащей Labelи именованный Label1``PictureBox1 , и Button Button1 PictureBoxсоответственно. Вставьте код в форму и свяжите Button1_Click метод с событием кнопки Click .
Комментарии
Растровое изображение состоит из данных пикселя для графического изображения и его атрибутов. Существует множество стандартных форматов для сохранения растрового изображения в файле. GDI+ поддерживает следующие форматы файлов: BMP, GIF, EXIF, JPG, PNG и TIFF. Дополнительные сведения о поддерживаемых форматах см. в разделе "Типы растровых изображений".
Класс Bitmap недоступен для доменов приложений. Например, если вы создаете динамическую AppDomain и создаете несколько кистей, перьев и растровых изображений в этом домене, то передайте эти объекты обратно в основной домен приложения, вы можете успешно использовать ручки и кисти. Однако если вызвать DrawImage метод для рисования маршалированного Bitmap, вы получите следующее исключение:
Удаленное взаимодействие не может найти поле "машинное изображение" в типе System.Drawing.Image.
Конструкторы
Инициализирует новый экземпляр класса Bitmap из указанного существующего изображения.
Инициализирует новый экземпляр класса Bitmap из указанного существующего изображения, масштабированного до заданного размера.
Инициализирует новый экземпляр класса Bitmap из указанного существующего изображения, масштабированного до заданного размера.
Инициализирует новый экземпляр класса Bitmap с заданным размером.
Инициализирует новый экземпляр класса Bitmap с заданным размером и с разрешением указанного объекта Graphics.
Инициализирует новый экземпляр класса Bitmap с заданным размером, форматом и данными пикселей.
Инициализирует новый экземпляр класса Bitmap с заданными значениями размера и формата.
Инициализирует новый экземпляр класса Bitmap из указанного потока данных.
Инициализирует новый экземпляр класса Bitmap из указанного потока данных.
Инициализирует новый экземпляр класса Bitmap из указанного файла.
Инициализирует новый экземпляр класса Bitmap из указанного файла.
Инициализирует новый экземпляр класса Bitmap из указанного ресурса.
Свойства
Возвращает флаги атрибутов для пиксельных данных этого объекта Image.
Возвращает массив идентификаторов GUID, представляющих размеры кадров в объекте Image.
Возвращает высоту объекта Image в пикселях.
Возвращает горизонтальное разрешение объекта Image в пикселях на дюйм.
Возвращает или задает палитру цветов, используемую для объекта Image.
Возвращает ширину и высоту данного изображения.
Возвращает формат пикселей для этого объекта Image.
Возвращает идентификаторы элементов свойств, хранящихся в объекте Image.
Возвращает все элементы свойств (части метаданных), хранящихся в объекте Image.
Возвращает формат файла этого объекта Image.
Возвращает ширину и высоту изображения в пикселях.
Возвращает или задает объект, предоставляющий дополнительные данные об изображении.
Возвращает вертикальное разрешение объекта Image в пикселях на дюйм.
Возвращает ширину объекта Image в пикселях.
Методы
Создает точную копию данного объекта Image.
Создает копию раздела этого объекта Bitmap, определяемого структурой Rectangle и с указанным перечислением PixelFormat.
Создает копию части этого изображения Bitmap, определяемого заданным перечислением PixelFormat.
Создает объект, который содержит всю необходимую информацию для создания прокси-сервера, используемого для взаимодействия с удаленным объектом.
Освобождает все ресурсы, используемые этим объектом Image.
Освобождает неуправляемые ресурсы, используемые объектом Image, а при необходимости освобождает также управляемые ресурсы.
Определяет, равен ли указанный объект текущему объекту.
Создает изображение Bitmap для значка из дескриптора Windows.
Создает изображение Bitmap из указанного ресурса Windows.
Возвращает границы изображения в указанных единицах измерения.
Возвращает информацию о параметрах, поддерживаемых указанным кодировщиком изображения.
Возвращает количество кадров указанного размера.
Служит хэш-функцией по умолчанию.
Создает объект растрового изображения GDI из этого Bitmapобъекта.
Создает объект растрового изображения GDI из этого Bitmapобъекта.
Возвращает дескриптор для значка.
Извлекает объект обслуживания во время существования, который управляет политикой времени существования данного экземпляра.
Возвращает цвет указанного пикселя в этом изображении Bitmap.
Возвращает указанный элемент свойства из объекта Image.
Возвращает эскиз для этого объекта Image.
Возвращает объект Type для текущего экземпляра.
Получает объект службы времени существования для управления политикой времени существования для этого экземпляра.
Блокирует объект Bitmap в системной памяти.
Блокирует объект Bitmap в системной памяти.
Делает прозрачным прозрачный цвет по умолчанию для этого элемента Bitmap.
Делает заданный цвет прозрачным для данного изображения Bitmap.
Создает неполную копию текущего объекта Object.
Создает неполную копию текущего объекта MarshalByRefObject.
Удаляет указанный элемент свойства из этого Image.
Поворачивает, зеркально отражает, либо поворачивает и зеркально отражает объект Image.
Сохраняет данное изображение в указанный поток с заданным кодировщиком и определенными параметрами кодировщика изображения.
Сохраняет данное изображение в указанный поток в указанном формате.
Сохраняет объект Image в указанный файл или поток.
Сохраняет объект Image в указанный файл с заданным кодировщиком и определенными параметрами кодировщика изображения.
Сохраняет объект Image в указанный файл в указанном формате.
Добавляет кадр в файл или поток, указанный в предыдущем вызове метода Save. Используйте данный метод для сохранения выбранных кадров из многокадрового изображения в другое многокадровое изображение.
Добавляет кадр в файл или поток, указанный в предыдущем вызове метода Save.
Выделяет кадр, определяемый размером и индексом.
Задает цвет указанного пикселя в этом объекте Bitmap.
Сохраняет элемент свойства (часть метаданных) в Image.
Задает разрешение для этого изображения Bitmap.
Возвращает строку, представляющую текущий объект.
Разблокирует это изображение Bitmap из оперативной памяти.
Явные реализации интерфейса
Заполняет объект SerializationInfo данными, необходимыми для сериализации целевого объекта.
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
Encapsulates a GDI+ bitmap, which consists of the pixel data for a graphics image and its attributes. A Bitmap is an object used to work with images defined by pixel data.
Examples
The following code example demonstrates how to construct a new Bitmap from a file, using the GetPixel and SetPixel methods to recolor the image. It also uses the PixelFormat, Width, and Height properties.
This example is designed to be used with a Windows Forms that contains a Label, PictureBox, and Button named Label1 , PictureBox1 , and Button1 , respectively. Paste the code into the form and associate the Button1_Click method with the button's Click event.
Remarks
A bitmap consists of the pixel data for a graphics image and its attributes. There are many standard formats for saving a bitmap to a file. GDI+ supports the following file formats: BMP, GIF, EXIF, JPG, PNG, and TIFF. For more information about supported formats, see Types of Bitmaps.
You can create images from files, streams, and other sources by using one of the Bitmap constructors and save them to a stream or to the file system with the Save method. Images are drawn to the screen or to memory by using the DrawImage method of the Graphics object. For a list of topics about working with image files, see Working with Images, Bitmaps, Icons, and Metafiles.
The Bitmap class is not accessible across application domains. For example, if you create a dynamic AppDomain and create several brushes, pens, and bitmaps in that domain, then pass these objects back to the main application domain, you can successfully use the pens and brushes. However, if you call the DrawImage method to draw the marshaled Bitmap, you receive the following exception:
Remoting cannot find field "native image" on type "System.Drawing.Image".
Constructors
Initializes a new instance of the Bitmap class from the specified existing image.
Initializes a new instance of the Bitmap class from the specified existing image, scaled to the specified size.
Initializes a new instance of the Bitmap class from the specified existing image, scaled to the specified size.
Initializes a new instance of the Bitmap class with the specified size.
Initializes a new instance of the Bitmap class with the specified size and with the resolution of the specified Graphics object.
Initializes a new instance of the Bitmap class with the specified size, pixel format, and pixel data.
Initializes a new instance of the Bitmap class with the specified size and format.
Initializes a new instance of the Bitmap class from the specified data stream.
Initializes a new instance of the Bitmap class from the specified data stream.
Initializes a new instance of the Bitmap class from the specified file.
Initializes a new instance of the Bitmap class from the specified file.
Initializes a new instance of the Bitmap class from a specified resource.
Properties
Gets attribute flags for the pixel data of this Image.
Gets an array of GUIDs that represent the dimensions of frames within this Image.
Gets the height, in pixels, of this Image.
Gets the horizontal resolution, in pixels per inch, of this Image.
Gets or sets the color palette used for this Image.
Gets the width and height of this image.
Gets the pixel format for this Image.
Gets IDs of the property items stored in this Image.
Gets all the property items (pieces of metadata) stored in this Image.
Gets the file format of this Image.
Gets the width and height, in pixels, of this image.
Gets or sets an object that provides additional data about the image.
Gets the vertical resolution, in pixels per inch, of this Image.
Gets the width, in pixels, of this Image.
Methods
Creates an exact copy of this Image.
Creates a copy of the section of this Bitmap defined by Rectangle structure and with a specified PixelFormat enumeration.
Creates a copy of the section of this Bitmap defined with a specified PixelFormat enumeration.
Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object.
Releases all resources used by this Image.
Releases the unmanaged resources used by the Image and optionally releases the managed resources.
Determines whether the specified object is equal to the current object.
Creates a Bitmap from a Windows handle to an icon.
Creates a Bitmap from the specified Windows resource.
Gets the bounds of the image in the specified unit.
Returns information about the parameters supported by the specified image encoder.
Returns the number of frames of the specified dimension.
Serves as the default hash function.
Creates a GDI bitmap object from this Bitmap.
Creates a GDI bitmap object from this Bitmap.
Returns the handle to an icon.
Retrieves the current lifetime service object that controls the lifetime policy for this instance.
Gets the color of the specified pixel in this Bitmap.
Gets the specified property item from this Image.
Returns a thumbnail for this Image.
Gets the Type of the current instance.
Obtains a lifetime service object to control the lifetime policy for this instance.
Locks a Bitmap into system memory.
Locks a Bitmap into system memory.
Makes the default transparent color transparent for this Bitmap.
Makes the specified color transparent for this Bitmap.
Creates a shallow copy of the current Object.
Creates a shallow copy of the current MarshalByRefObject object.
Removes the specified property item from this Image.
Rotates, flips, or rotates and flips the Image.
Saves this image to the specified stream, with the specified encoder and image encoder parameters.
Saves this image to the specified stream in the specified format.
Saves this Image to the specified file or stream.
Saves this Image to the specified file, with the specified encoder and image-encoder parameters.
Saves this Image to the specified file in the specified format.
Adds a frame to the file or stream specified in a previous call to the Save method. Use this method to save selected frames from a multiple-frame image to another multiple-frame image.
Adds a frame to the file or stream specified in a previous call to the Save method.
Selects the frame specified by the dimension and index.
Sets the color of the specified pixel in this Bitmap.
Stores a property item (piece of metadata) in this Image.
Sets the resolution for this Bitmap.
Returns a string that represents the current object.
Unlocks this Bitmap from system memory.
Explicit Interface Implementations
Populates a SerializationInfo with the data needed to serialize the target object.
A bitmap is an array of bits that specify the color of each pixel in a rectangular array of pixels. The number of bits devoted to an individual pixel determines the number of colors that can be assigned to that pixel. For example, if each pixel is represented by 4 bits, then a given pixel can be assigned one of 16 different colors (2^4 = 16). The following table shows a few examples of the number of colors that can be assigned to a pixel represented by a given number of bits.
Bits per pixel | Number of colors that can be assigned to a pixel |
---|---|
1 | 2^1 = 2 |
2 | 2^2 = 4 |
4 | 2^4 = 16 |
8 | 2^8 = 256 |
16 | 2^16 = 65,536 |
24 | 2^24 = 16,777,216 |
Disk files that store bitmaps usually contain one or more information blocks that store information such as the number of bits per pixel, number of pixels in each row, and number of rows in the array. Such a file might also contain a color table (sometimes called a color palette). A color table maps numbers in the bitmap to specific colors. The following illustration shows an enlarged image along with its bitmap and color table. Each pixel is represented by a 4-bit number, so there are 2^4 = 16 colors in the color table. Each color in the table is represented by a 24-bit number: 8 bits for red, 8 bits for green, and 8 bits for blue. The numbers are shown in hexadecimal (base 16) form: A = 10, B = 11, C = 12, D = 13, E = 14, F = 15.
Look at the pixel in row 3, column 5 of the image. The corresponding number in the bitmap is 1. The color table tells us that 1 represents the color red so the pixel is red. All the entries in the top row of the bitmap are 3. The color table tells us that 3 represents blue, so all the pixels in the top row of the image are blue.
Some bitmaps are stored in bottom-up format; the numbers in the first row of the bitmap correspond to the pixels in the bottom row of the image.
A bitmap that stores indexes into a color table is called a palette-indexed bitmap. Some bitmaps have no need for a color table. For example, if a bitmap uses 24 bits per pixel, that bitmap can store the colors themselves rather than indexes into a color table. The following illustration shows a bitmap that stores colors directly (24 bits per pixel) rather than using a color table. The illustration also shows an enlarged view of the corresponding image. In the bitmap, FFFFFF represents white, FF0000 represents red, 00FF00 represents green, and 0000FF represents blue.
Graphics File Formats
There are many standard formats for saving bitmaps in disk files. GDI+ supports the graphics file formats described in the following paragraphs.
BMP is a standard format used by Windows to store device-independent and application-independent images. The number of bits per pixel (1, 4, 8, 15, 24, 32, or 64) for a given BMP file is specified in a file header. BMP files with 24 bits per pixel are common. BMP files are usually not compressed and, therefore, are not well suited for transfer across the Internet.
Graphics Interchange Format (GIF)
GIF is a common format for images that appear on Web pages. GIFs work well for line drawings, pictures with blocks of solid color, and pictures with sharp boundaries between colors. GIFs are compressed, but no information is lost in the compression process; a decompressed image is exactly the same as the original. One color in a GIF can be designated as transparent, so that the image will have the background color of any Web page that displays it. A sequence of GIF images can be stored in a single file to form an animated GIF. GIFs store at most 8 bits per pixel, so they are limited to 256 colors.
Joint Photographic Experts Group (JPEG)
JPEG is a compression scheme that works well for natural scenes such as scanned photographs. Some information is lost in the compression process, but often the loss is imperceptible to the human eye. JPEGs store 24 bits per pixel, so they are capable of displaying more than 16 million colors. JPEGs do not support transparency or animation.
The level of compression in JPEG images is configurable, but higher compression levels (smaller files) result in more loss of information. A 20:1 compression ratio often produces an image that the human eye finds difficult to distinguish from the original. The following illustration shows a BMP image and two JPEG images that were compressed from that BMP image. The first JPEG has a compression ratio of 4:1 and the second JPEG has a compression ratio of about 8:1.
JPEG compression does not work well for line drawings, blocks of solid color, and sharp boundaries. The following illustration shows a BMP along with two JPEGs and a GIF. The JPEGs and the GIF were compressed from the BMP. The compression ratio is 4:1 for the GIF, 4:1 for the smaller JPEG, and 8:3 for the larger JPEG. Note that the GIF maintains the sharp boundaries along the lines, but the JPEGs tend to blur the boundaries.
JPEG is a compression scheme, not a file format. JPEG File Interchange Format (JFIF) is a file format commonly used for storing and transferring images that have been compressed according to the JPEG scheme. JFIF files displayed by Web browsers use the .jpg extension.
Exchangeable Image File (EXIF)
EXIF is a file format used for photographs captured by digital cameras. An EXIF file contains an image that is compressed according to the JPEG specification. An EXIF file also contains information about the photograph (date taken, shutter speed, exposure time, and so on) and information about the camera (manufacturer, model, and so on).
Portable Network Graphics (PNG)
The PNG format retains many of the advantages of the GIF format but also provides capabilities beyond those of GIF. Like GIF files, PNG files are compressed with no loss of information. PNG files can store colors with 8, 24, or 48 bits per pixel and grayscales with 1, 2, 4, 8, or 16 bits per pixel. In contrast, GIF files can use only 1, 2, 4, or 8 bits per pixel. A PNG file can also store an alpha value for each pixel, which specifies the degree to which the color of that pixel is blended with the background color.
PNG improves on GIF in its ability to progressively display an image (that is, to display better and better approximations of the image as it arrives over a network connection). PNG files can contain gamma correction and color correction information so that the images can be accurately rendered on a variety of display devices.
Tag Image File Format (TIFF)
TIFF is a flexible and extendable format that is supported by a wide variety of platforms and image-processing applications. TIFF files can store images with an arbitrary number of bits per pixel and can employ a variety of compression algorithms. Several images can be stored in a single, multiple-page TIFF file. Information related to the image (scanner make, host computer, type of compression, orientation, samples per pixel, and so on) can be stored in the file and arranged through the use of tags. The TIFF format can be extended as needed by the approval and addition of new tags.
BMP (BitMaP) - основной метод хранения несжатых графических файлов. Фотография с 6-ти мегапискельного фотоаппарата в этом формате будет иметь размер 18М байт.
В начале 2000-х годов Microsoft пыталась сделать BMP-файлы основным видом графических файлов. В связи с этим была добавлена возможность хранения в этих файлах графических файлов других графических форматов (включая png, jpeg и др.). Но сейчас от этой идеи отказались и BMP-файлы используются лишь для хранения несжатых изображений.
Помимо базового варианта (3 байта на точку, BMP-24) может быть "серый" файл (1 байт на точку) и некоторые другие. Далее мы будем рассматриать только файлы формата BMP-24.
Строчки в bmp-файле хранятся в обратном порядке, то есть в начале идет самая нижняя строка изображения. Внутри строки байты имеют порядок BGR BGR . Кроме того, длина каждой строки выровнена до кратного четырех. То есть для изображения шириной 3 точки длина строки равна 12 байт (3 точки по 3 байта, всего 9 байт, затем увеличиваем длину строки до кратного 4).
В начале bmp-файла идет заголовок следующей структуры: Отметим, что в этом примере кода тип int предполагается 32-битовым. Если в вашем случае это не так, то вместо int надо использовать тип 4-х байтового целого числа. Аналогично, __int16 означает 16-битовое целое число. Если ваш компилятор такого идентификатора не знает, то его надо заменить на соответствующий.
Чтение файла формата BMP-24 можно осуществить следующей функцией. В переменных mx,my возвращаются размеры файла. Для графических данных функция выделяет память (new int[mx*my]). Именно этот указатель и возвращатся в качестве результата. Он указывает на одномерный массив целых чисел, в котором лежат последовательно цветовые значения всех пикселей изображения. В каждое целое 4-х байтовое число упаковано по 3 байта RGB в формате R + 256*G + 65536*B. В случае какой-либо ошибки память не выделяется, возвращается NULL.
ВНИМАНИЕ!. Освобождать память должна будет программа, вызвавшая данную функцию, например: Для записи в BMP-файл можно использовать фунцию
Читайте также: