В отличие от обычных 16-, 24- и 32-битных цветовых форматов BMP, индексированное растровое изображение — это формат растрового изображения, в котором используется палитра + 8-битный цвет, каждый пиксель занимает только один байт, а значение пикселя составляет индекс 0–255. цвет сохраняется в соответствующей позиции данных палитры
Создание индексированных растровых изображений в Photoshop
Используйте Photoshop, чтобы открыть существующее изображение, а затем выберите меню [Изображение], [Режим], [Индексированный цвет...]. Затем
во всплывающем диалоговом окне вы можете выбрать соответствующий алгоритм для сортировки индексированного цвета и суммировать цвета текущего изображения в один из 256 цветов.После подтверждения в середине
изображение становится индексным растровым изображением.Через меню [Изображение],[Режим],[Таблица цветов...] снова можно изменить содержимое палитры, а затем [Сохранить как...], чтобы сохранить его в
формате 8-битного цветного изображения BMP.
GIMP делает индексированные растровые изображения
Через меню 【Изображение】, 【Режим】, 【Индекс...】
всплывающее диалоговое окно преобразует изображение в индексированный цвет,
а затем через меню 【Окно】, 【Прикрепляемое диалоговое окно】, 【Таблица цветов 】
чтобы открыть панель цветной поверхности, вы можете использовать ее в дальнейшем Укажите цвет и значение индекса в операции.После
редактирования вам нужно выбрать изображение Windows BMP через меню [Файл], [Экспорт... ] и может быть сгенерирован 8-битный битовый индекс
Представьте растровое изображение индекса просмотра и таблицу цветов
Imagine — это легкий бесплатный браузер изображений, который может легко просматривать различные форматы изображений, официальный сайт: https://www.nyam.pe.kr/dev/imagine/
. При открытии индексного растрового изображения вы можете использовать 【Edit Palette】. кнопка для открытия окна палитры
Формат файла индексированного растрового изображения
Обратитесь к документу msdn: https://docs.microsoft.com/zh-cn/windows/win32/gdi/bitmap-storage , видно, что формат хранения растрового изображения
Формат BITMAPFILEHEADER
Заявлено в заголовочном файле Wingdi.h
член | иллюстрировать |
---|---|
бфТип | 0x4D42, что указывает на BM |
bfSize | Общий размер файла, включая размер BITMAPFILEHEADER. |
бфрезервед1 | 0 |
bfReserved2 | 0 |
бфоффбитс | Начальная позиция данных изображения (массив цветовых индексов) относительно заголовка файла. |
Формат BITMAPINFHEADER
Заявлено в заголовочном файле Wingdi.h
член | иллюстрировать |
---|---|
биразмер | Размер структуры BITMAPINFOHEADER 40 |
biWidth | ширина изображения |
биВысота | высота изображения |
бипланы | 1 |
бибиткаунт | растровое изображение индекса равно 8 |
бикомпрессия | BI_RGB означает несжатый |
biSizeImage | Размер данных изображения, обычно шаг x biHeight, шаг: 4-байтовая выровненная версия biWidth * sizeof(pixel) |
biXPelsPerMeter | пикселей на метр |
biYPelsPerMeter | пикселей на метр |
biClrUsed | Битовая карта индекса равна 0, что указывает на то, что палитра имеет 256 цветов. |
biClrВажно | 0 |
Чтение растрового изображения индекса в C++
Предположим, вам нужно прочитать растровое изображение в двумерный массив boost::multi_array<byte, 2> img
std::ifstream ifs("aaa.bmp", std::ios::binary);
//- bfh {bfType=19778 bfSize=787512 bfReserved1=0 ...} tagBITMAPFILEHEADER
// bfType 19778 unsigned short
// bfSize 787512 unsigned long
// bfReserved1 0 unsigned short
// bfReserved2 0 unsigned short
// bfOffBits 1078 unsigned long
BITMAPFILEHEADER bfh;
ifs.read((char*)&bfh, sizeof(bfh));
if (bfh.bfType != 0x4D42)
return;
//- bih {biSize=40 biWidth=1024 biHeight=768 ...} tagBITMAPINFOHEADER
// biSize 40 unsigned long
// biWidth 1024 long
// biHeight 768 long
// biPlanes 1 unsigned short
// biBitCount 8 unsigned short
// biCompression 0 unsigned long
// biSizeImage 786434 unsigned long
// biXPelsPerMeter 11808 long
// biYPelsPerMeter 11808 long
// biClrUsed 0 unsigned long
// biClrImportant 0 unsigned long
BITMAPINFOHEADER bih;
ifs.read((char*)&bih, sizeof(bih));
if (bih.biCompression != BI_RGB || bih.biBitCount != 8)
return;
// 位图每一行的数据字节长度是4的倍数
int pitch = (bih.biWidth * bih.biBitCount + 31) / 32 * 4;
// 逐行将数据读入二维数组
boost::multi_array<unsigned char, 2> img(boost::extents[bih.biHeight][bih.biWidth]);
for (int i = 0; i < bih.biHeight; i++)
{
// Windows位图数据从下往上存储,所以需要反着读取
long offset = bfh.bfOffBits + (bih.biHeight - i - 1) * pitch;
ifs.seekg(offset, SEEK_SET);
ifs.read((char*)&img[i][0], bih.biWidth * sizeof(unsigned char));
}
Написать растровое изображение индекса на C++
После чтения bfh и bih растрового изображения данные уже были видны в памяти, поэтому следуйте тому же шаблону, а затем запишите данные обратно в файл, но поскольку данные ширины растрового изображения должны быть кратны 4, это рекомендуется сохранить исходный массив соответственно расширить
// boost::multi_array<unsigned char, 2> img(...);
// 需要将二维数组img的宽度扩大到4的倍数
img.resize(boost::extents[img.shape()[0]][boost::alignment::align_up(img.shape()[1], 4)]);
std::ofstream ofs(path, std::ios::binary, _SH_DENYRW);
BITMAPFILEHEADER bfh = {
0 };
BITMAPINFOHEADER bih = {
0 };
bfh.bfType = 0x4D42;
bfh.bfOffBits = sizeof(bfh) + sizeof(bih) + sizeof(RGBQUAD) * 256;
bfh.bfSize = bfh.bfOffBits + img.num_elements() * sizeof(unsigned char);
bih.biSize = sizeof(bih);
bih.biWidth = img.shape()[1];
bih.biHeight = img.shape()[0];
bih.biPlanes = 1;
bih.biBitCount = 8;
bih.biCompression = BI_RGB;
bih.biSizeImage = img.num_elements() * sizeof(unsigned char);
bih.biXPelsPerMeter = 11808;
bih.biYPelsPerMeter = 11808;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
ofs.write((char*)&bfh, sizeof(bfh));
ofs.write((char*)&bih, sizeof(bih));
// 这里写入灰度数据到调色板数据,可在Photoshop面板中更改
for (int p = 0; p < 256; p++)
{
RGBQUAD q = {
p, p, p, 0 };
ofs.write((char*)&q, sizeof(q));
}
for (int i = 0; i < img.shape()[0]; i++)
{
ofs.write((char*)&img[img.shape()[0] - i - 1][0], img.shape()[1] * sizeof(unsigned char));
}
Ссылка:
https://docs.microsoft.com/zh-cn/windows/win32/gdi/bitmap-storage
https://blog.csdn.net/Wintalen/article/details/1014820
https://sunriver2000.blog. csdn.net/статья/детали/104251831