-
Alexander (09.01.09 17:40) [0]Уже был тут, вопрос формулировал по-другому. И всё-таки:
Как имеющийся файл Bmp 16 или 24 битной кодировки цветности программно конвертировать в 256 цветов?
Желательно, работать с bmp загруженным в TBitmap -
Alexander (09.01.09 18:33) [1]Ответ оказался до стыдности простым.
pf := pf8bit;
bmp.PixelFormat := pf;
Снято. -
KilkennyCat © (10.01.09 14:56) [2]зря снято.
это вовсе не конвертация. -
Вася (26.01.10 12:48) [3]> это вовсе не конвертация.
конвертация.=)
класс-обёртка после этого действительно конвертирует,только там алгоритм уменьшения цветов плохой.
вот если уменьшать кол-во цветов - тогда лучше вручную, а увеличивать и так сойдёт...=) -
ViT (04.02.15 16:48) [4]Вопрос немного другой, но суть та же:
есть Bitmap, читаю для него палитру из 255 цветов из файла, присваиваю её:
GetMem(logPal, sizeof(TLogPalette) + sizeof(TPaletteEntry) * 255);
logpal.palVersion:=$300;
logpal.palNumEntries:=256;
bmp.Palette:=CreatePalette(logPal^);
читаю данные для Bitmap из RAW файла, всё нормально, цвета отображаются как надо.
но как мне теперь сохранить bmp с этой палитрой?
bmp.SaveToFile(SaveDialog1.FileName) сохраняет да, но палитра 32битная, а не моя 255 цветов.
делаю:
bmp.PixelFormat:=pf8bit;
bmp.SaveToFile(SaveDialog1.FileName)
сохраняет, палитра моя, но цвета конечной картинки получаются немного искажены(
я думаю что проблема в том, что я изначально работаю с bmp.PixelFormat:=pf24bit, но если поставить изначально bmp.PixelFormat:=pf8bit, а потом читать данные в bmp, то мой алгоритм чтения вылетает с ошибкой
читаю так:for y:=0 to 512-1 do
begin
Dest:=bmp.ScanLine[y];
for I := 0 to 512-1 do
begin
fs.ReadBuffer(b, 1);
Dest[i].r:=logPal.palPalEntry[b].peRed;
Dest[i].g:=logPal.palPalEntry[b].peGreen;
Dest[i].b:=logPal.palPalEntry[b].peBlue;
end;
end; -
invis © (05.02.15 06:19) [5]В том и смысл 8-битных битмапов, что пиксели хранятся там в виде индексов в палитре. То есть вот это b, которое ты читаешь из файла, нужно писать в битмап без преобразования в RGB.
-
ViT (05.02.15 09:55) [6]invis, так я же и беру индекс из палитры:
читаю из файла 1 байт - это индекс в палитреfs.ReadBuffer(b, 1);
и присваиваю точке цвет по этому индексу в палитреDest[i].r:=logPal.palPalEntry[b].peRed;
Dest[i].g:=logPal.palPalEntry[b].peGreen;
Dest[i].b:=logPal.palPalEntry[b].peBlue; -
> но цвета конечной картинки получаются немного искажены(
- потому что по умолчанию применяется стандартная кубическая палитра(HALFTONE - 20 системных + 6*6*6 куб + 20 "резервных"), а нужна адаптивная...
https://en.wikipedia.org/wiki/List_of_software_palettes
http://www.microsoft.com/msj/archive/S3F1.aspx -
ViT (05.02.15 13:24) [8]han_malign, ну я это в принципе так и понимал, так а что сделать тогда нужно чтобы сохранилось с моей палитрой?
-
> а что сделать тогда нужно чтобы сохранилось с моей палитрой?
- "а вот фиг - сказала репка - я здесь сижу довольно крепко"(с)...
GDI(bitblt) - умеет "палитровать" только в стандартную HALFTONE полученную через CreateHalftonePalette(), либо в 20-ть первых системных...
Всё остальное - исключительно вручную...
Ну или в сторону GDI+/сторонних покопать... -
MBo © (05.02.15 15:08) [10]SetDIBColorTable
-
invis © (05.02.15 15:45) [11]и присваиваю точке цвет по этому индексу в палитре
Нет, присваивать цвет будет система при выводе картинки на экран. А тебе нужно писать в битмап индекс в палитре.
По поводу сторонних компонентов, рекомендую FastLIB (TFastDIB), там с палитрой проще работать. -
ViT (05.02.15 15:58) [12]invis, блин, дошло)
даже в хелпе написано что для 8bit надо использовать PByteArray, и писать номер индекса в него, а я использовал RGB запись, и в каждый цвет шло только по 15 значений, а не 255 как я в него пихал, поэтому и была ошибка.
всем спасибо.
p.s. Просто цель была сделать универсальный конвертор в BMP raw данных 15/8/4 битных. Поэтому bmp ставил pf24bit всегда. Хотя как вариант можно создавать второй bmp нужной битности и нужной палитры, и попиксельно копировать в него из первого bmp.