HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Half-Life SDK (https://hlfx.ru/forum/forumdisplay.php?forumid=8)
-- C++ Конвертирование BMP 24 -> 8 bit (https://hlfx.ru/forum/showthread.php?threadid=2468)
Отправлено fire64 26-11-2010 в 18:35:
C++ Конвертирование BMP 24 -> 8 bit
Написал код для конвертирования 24 битных BMP в 8 битные.
В чем суть: считываем из пикселей цвета и заполняем ими палитру, а вместо цветов ставим индекс цвета из палитры.
Потом записываем заголовки + палитра + пиксели.
По неизвестной мне причине, вместо нормального 8 битного изображения получается что-то странное.
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено XaeroX 26-11-2010 в 18:40:
Где изображение этого "странного"?
Ты ж не думаешь всеръез, что мы будем программу запускать?
__________________
Отправлено fire64 26-11-2010 в 18:41:
Посмотри в папке Debug
test.bmp - оригинал
new.bmp - конвертированная версия.
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 26-11-2010 в 19:34:
Цитата:
fire64 писал:
считываем из пикселей цвета и заполняем ими палитру, а вместо цветов ставим индекс цвета из палитры.
плакал. Ты всеръез думаешь что палитру можно заполнить тупым копированием цветов из RGB24 ?__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено XaeroX 26-11-2010 в 19:41:
fire64
У меня new.bmp не открывается, пишет, что ошибка в файле. Ты что, не мог как следовает изучить bmp-формат? 
Добавлено 27-11-2010 в 01:41:
Очень похоже на то, что ты что-то в формате файла начудил.
__________________
Отправлено fire64 26-11-2010 в 19:55:
Дядя Миша, хм.
А разве цвет в палитре не задается с помощью 4 байт r, g, b, reserve ?
Вроде бы в 24 битном формате цвет пикселя задается также.
Логично, что палитра имеет 255 слотов под цвета.
А в самом изображении RGBRes заменяется на индекс идентичного цвета в палитре.
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 26-11-2010 в 20:01:
fire64 на вот тебе для затравки
Почему картинка смещается - ищи сам. Ненавижу эту фишку бмп.
Добавлено 26-11-2010 в 23:01:
Цитата:
fire64 писал:
Логично, что палитра имеет 255 слотов под цвета.
ну хорошо, твой метод проканает для ч\б картинок и рисунков, нарисованных фпаинте. Но для боле-мене полноцветной картинки - никогда.__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено fire64 26-11-2010 в 20:23:
Дядя Миша, если в оригинале, количество цветов больше чем 256, то тогда надо будет менять код GetOrAddPixeltoPallet.
Нужно будет работать с областью значений и подбирать наиболее схожие цвета.
Кстати, почему
C++ Source Code:
for( int i = 0; i < countpixel * 3; i+=3 ) |
Мы же по логике должны смещаться на 4 байта.
Ведь пиксель в 24 битном формате имеет вида:
byte r
byte g
byte b
byte reserve__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 26-11-2010 в 20:29:
Цитата:
fire64 писал:
Нужно будет работать с областью значений и подбирать наиболее схожие цвета.
ну и на выходе получится гамно, можешь быть уверен.
Квантизатор цветового пространства - это архи-сложная вещь, сравнимая с кодированием звукового сигнала в мп3 с учетом психо-акустических особенностей человеческого организма. Для завтравки - посмотри квантизатор из хл2 бетки.
Согласись, что он "слегка" сложнее тупого подбора похожего цвета.
И это еще не самый лучший квантизатор.
Добавлено 26-11-2010 в 23:29:
Цитата:
fire64 писал:
Мы же по логике должны смещаться на 4 байта.
ну смещайся, кто тебе запрещает? Только потом не жалуйся, что картинку вьювер не открывает.
Цитата:
fire64 писал:
Ведь пиксель в 24 битном формате имеет вида:
byte r
byte g
byte b
byte reserve
Удивительные открытия - каждый день! Это ктож тебя так обманул?
Покажи пальцем, я его сам забаню за распространение ложных слухов.__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено fire64 26-11-2010 в 20:40:
Насчет 4 байт для пикселей, кажется читал в вики.
Мда, все оказывается намного сложней.
Я надеялся, что можно просто в GetOrAddPixeltoPallet заменить
C++ Source Code:
if( Palette[i].rgbRed == pRgbData.r && Palette[i].rgbGreen == pRgbData.g && Palette[i].rgbBlue == pRgbData.b ) |
на
C++ Source Code:
if( CompareColor( Palette[i], pRgbData, 30 ) ) |
C++ Source Code:
1 | bool CompareColor( RGBQUAD Palette, rgbdata_t pRgbData, int maxvalue ) |
3 | if( Palette.rgbRed + maxvalue < pRgbData.r || Palette.rgbRed - maxvalue > pRgbData.r ) |
8 | if( Palette.rgbGreen + maxvalue < pRgbData.g || Palette.rgbGreen - maxvalue > pRgbData.g ) |
13 | if( Palette.rgbBlue + maxvalue < pRgbData.b || Palette.rgbBlue - maxvalue > pRgbData.b ) |
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 26-11-2010 в 20:45:
Цитата:
fire64 писал:
Насчет 4 байт для пикселей, кажется читал в вики.
это для 32-битных картинок.
Цитата:
fire64 писал:
Я надеялся, что можно просто в GetOrAddPixeltoPallet заменить
можно, но
Цитата:
Дядя Миша писал:
на выходе получится гамно, можешь быть уверен.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено XaeroX 26-11-2010 в 20:47:
Цитата:
fire64 писал:
Насчет 4 байт для пикселей, кажется читал в вики.
А в наше время молодежь читала MSDN... =\__________________
Отправлено fire64 26-11-2010 в 20:52:
Только что, взял свой аватар и сохранил в 24 битном bmp.
Изображение нормально сконвертировалось, но перепутались цветовые каналы.
вместо RGB, BGR
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 26-11-2010 в 21:04:
Здрасти. Ну BMP это и есть BGR.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено SiPlus 27-11-2010 в 12:36:
fire64, в 24-х битном BMP для покраски пикселов надо 3 байта (b,g,r). Никаких реверсов там нет. Да и из количества битов все понятно. Это тебе не 32-битный BMP.
Отправлено Дядя Миша 27-11-2010 в 12:52:
Цитата:
SiPlus писал:
Никаких реверсов там нет
что за реверсы-то?__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено SiPlus 27-11-2010 в 15:06:
Цитата:
Дядя Миша писал:
что за реверсы-то?
Цитата:
fire64 писал:
byte r
byte g
byte b
byte reserve
Добавлено 27-11-2010 в 18:06:
Ой, не реверсы, а резервы. Кстати, зачем они вообще нужны?
Отправлено Дядя Миша 27-11-2010 в 16:59:
нету там никакого резерва. Это ты со структурой RGBQUAD перопутал.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено fire64 28-11-2010 в 08:18:
Новая версия.
Кажется во всех вьюверах теперь открывается.
добавил небольшие изменение, для увеличения количества настоящих цветов за счет принудительного превращения в черные и белы цвета
Добавлено 28-11-2010 в 11:18:
Держите новую версию.
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено CrazyRussian 28-11-2010 в 08:20:
По поводу краша с RGBQUAD FullImageColors[16777216];
C++ Source Code:
1 | RGBQUAD*FullImageColors; |
2 | FullImageColors=(RGBQUAD*)malloc(sizeof(RGBQUAD)*16777216); |
3 | //работаем с FullImageColors |
__________________
Трагическая новость: Пятеро инженеров Casio умерли от смеха, узнав что Samsung анонсировали часы с заявленным временем работы в 25 часов
Отправлено fire64 28-11-2010 в 09:48:
Добавил "смешивание цветов", а так же переменные для настройки конвертирования.
Добавлено 28-11-2010 в 12:48:
Новая версия.
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 28-11-2010 в 09:53:
fire64 ну это не смешно, честное слово.
твоя картинка должна выглядеть вот так (см. аттач)
иначе всё это просто никому не нужно.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено fire64 10-01-2011 в 16:46:
Дядя Миша, возобновляю старую тему.
Новый алгоритм заполнения палитры 
Результат конечно не как от хорошего квантоватора, но имхо все же лучше чем ничего 
Добавлено 10-01-2011 в 19:46:
Да и результаты вполне вменяемые.
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено fire64 11-01-2011 в 14:11:
Я решил пойти дальше и написать конвертер Vtf2WAD.
Однако столкнулся со странной проблемой.
DevIL.dll сохраняет изображение в какой-то нестандартный тип BMP.
И в результате мой конвертер 24->8bpp просто падает.
cкачать исходники и программу
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Ku2zoff 11-01-2011 в 14:26:
fire64 а ты в BMP не сохраняй, сохраняй в TGA или DDS
Зачем нужен vtf2wad? Много текстур размером 2048x1024 наконвертируешь в хл вад? Нужен wad2vtf!
Отправлено fire64 11-01-2011 в 14:42:
Все разобрался.
DevIL сохраняет BMP файл с bih.biSizeImage равным 0
Пришлось вместо
bih.biSizeImage
использовать
bfh.bfSize - bfh.bfOffBits
Теперь vtf нормально конвертится и сохраняет в 8 битный bmp
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 11-01-2011 в 15:16:
fire64 ты конвертируй с учетом всех сторон кубимапы и вообще многокадровые изображения распаковывай нормально.
Дать загрузчик VTF из ксаша?
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено fire64 11-01-2011 в 15:26:
Пипец.
Qlumpy отказывается жрать файл размером 512x512.
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 11-01-2011 в 15:37:
Цитата:
fire64 писал:
Qlumpy отказывается жрать файл размером 512x512.
зато xwad - прекрасно кушает 
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено fire64 11-01-2011 в 16:19:
А исходники у xwad есть ?
Добавлено 11-01-2011 в 19:19:
Исправил "фичу" из-за которой приходилось в скрипте указывать полный путь до BMP файла и добавил поддержку больших текстур.
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 11-01-2011 в 17:09:
Цитата:
fire64 писал:
А исходники у xwad есть ?
а как жы.
Добавлено 11-01-2011 в 20:09:
Загрузчик VTF для нашего друга 
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено fire64 13-01-2011 в 11:01:
В общем все прекрасно за исключением того, что половина BMP файлов получаются кривыми.
__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 13-01-2011 в 11:36:
fire64 дать сохранялку бмп? Правда у меня только для 8-бит. но сохраняет жылезна.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено fire64 13-01-2011 в 11:56:
Разобрался.
Дело в том, что в BMP есть такое понятие как выравнивание.
То есть, дополнительные байты в конце каждой строки.
C++ Source Code:
int optimgsize = bih.biWidth * bih.biHeight * 3; |
int relimgsize = bfh.bfSize - bfh.bfOffBits; |
Соответственно если optimgsize и relimgsize равны, то пустых байтов нет и изображение нормально сохраняется.
Если же relimgsize больше optimgsize, то нужно дополнительно производить смещение в конце строки на relimgsize / optimgsize.__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 13-01-2011 в 12:30:
Цитата:
fire64 писал:
Дело в том, что в BMP есть такое понятие как выравнивание.
Я не понял, это ты мне рассказываешь?
твой код, кстати неправильный.__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено fire64 13-01-2011 в 12:32:
Короче сделал так:
C++ Source Code:
1 | int optimgsize = bih.biWidth * bih.biHeight * 3; |
2 | int relimgsize = bfh.bfSize - bfh.bfOffBits; |
4 | int countpixels = bih.biWidth * bih.biHeight; |
5 | int countbytesalignment = relimgsize - optimgsize; |
10 | if( relimgsize == optimgsize ) |
16 | alignmentsize = countbytesalignment / countpixels; |
18 | pixeloffset = 3 + alignmentsize; |
Теперь все изображения успешно сохраняются.__________________
Вся сила лысого кощея,
Сокрыта в башне из костей
Воздвигнутой, под небесами
На месте похорон людей
Отправлено Дядя Миша 13-01-2011 в 12:53:
C++ Source Code:
1 | qboolean Image_SaveBMP( const char *name, rgbdata_t *pix ) |
6 | RGBQUAD rgrgbPalette[256]; |
9 | byte *pb, *pbPal = NULL; |
14 | if( FS_FileExists( name, false ) && !(image.cmd_flags & IL_ALLOW_OVERWRITE )) |
15 | return false; // already existed |
17 | // bogus parameter check |
18 | if( !pix->palette || !pix->buffer ) |
27 | MsgDev( D_WARN, "Image_SaveBMP: unsupported image type %s\n", PFDesc[pix->type].name ); |
31 | pfile = FS_Open( name, "wb", false ); |
32 | if( !pfile ) return false; |
34 | // NOTE: align transparency column will sucessfully removed |
35 | // after create sprite or lump image, it's just standard requiriments |
36 | biTrueWidth = ((pix->width + 3) & ~3); |
37 | cbBmpBits = biTrueWidth * pix->height; |
38 | cbPalBytes = 256 * sizeof( RGBQUAD ); |
40 | // Bogus file header check |
41 | bmfh.bfType = MAKEWORD( 'B', 'M' ); |
42 | bmfh.bfSize = sizeof(bmfh) + sizeof(bmih) + cbBmpBits + cbPalBytes; |
45 | bmfh.bfOffBits = sizeof(bmfh) + sizeof(bmih) + cbPalBytes; |
48 | FS_Write( pfile, &bmfh, sizeof(bmfh)); |
51 | bmih.biSize = sizeof(bmih); |
52 | bmih.biWidth = biTrueWidth; |
53 | bmih.biHeight = pix->height; |
56 | bmih.biCompression = BI_RGB; |
58 | bmih.biXPelsPerMeter = 0; |
59 | bmih.biYPelsPerMeter = 0; |
61 | bmih.biClrImportant = 0; |
64 | FS_Write( pfile, &bmih, sizeof(bmih)); |
67 | // copy over used entries |
68 | for( i = 0; i < (int)bmih.biClrUsed; i++ ) |
70 | rgrgbPalette[i].rgbRed = *pb++; |
71 | rgrgbPalette[i].rgbGreen = *pb++; |
72 | rgrgbPalette[i].rgbBlue = *pb++; |
74 | // bmp feature - can store 32-bit palette if present |
75 | // some viewers e.g. fimg.exe can show alpha-chanell for it |
76 | if( pix->type == PF_INDEXED_32 ) |
77 | rgrgbPalette[i].rgbReserved = *pb++; |
78 | else rgrgbPalette[i].rgbReserved = 0; |
81 | // make last color is 0 0 255, xwad expect this (but ignore decals) |
82 | if( com.strrchr( name, '{' ) && pix->flags & IMAGE_HAS_ALPHA && !( pix->flags & IMAGE_COLORINDEX )) |
84 | rgrgbPalette[255].rgbRed = 0x00; |
85 | rgrgbPalette[255].rgbGreen = 0x00; |
86 | rgrgbPalette[255].rgbBlue = 0xFF; |
87 | rgrgbPalette[255].rgbReserved = 0x00; |
90 | // write palette( bmih.biClrUsed entries ) |
91 | cbPalBytes = bmih.biClrUsed * sizeof( RGBQUAD ); |
92 | FS_Write( pfile, rgrgbPalette, cbPalBytes ); |
93 | pbBmpBits = Mem_Alloc( Sys.imagepool, cbBmpBits ); |
94 | Mem_Set( pbBmpBits, 0xFF, cbBmpBits ); // fill buffer with last palette color |
97 | pb += (pix->height - 1) * pix->width; |
99 | for( i = 0; i < bmih.biHeight; i++ ) |
101 | Mem_Copy( &pbBmpBits[biTrueWidth * i], pb, pix->width ); |
105 | // write bitmap bits (remainder of file) |
106 | FS_Write( pfile, pbBmpBits, cbBmpBits ); |
108 | Mem_Free( pbBmpBits ); |
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'