Конференция "Media" » Конвертирование BMP 16 bit или 24 bit > BPM 256 цветов [D6, D7, Win2k, WinXP]
 
  • 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;

  • han_malign © (05.02.15 10:47) [7]

    > но цвета конечной картинки получаются немного искажены(

    - потому что по умолчанию применяется стандартная кубическая палитра(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, ну я это в принципе так и понимал, так а что сделать тогда нужно чтобы сохранилось с моей палитрой?
  • han_malign © (05.02.15 14:44) [9]

    > а что сделать тогда нужно чтобы сохранилось с моей палитрой?

    - "а вот фиг - сказала репка - я здесь сижу довольно крепко"(с)...
    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.
 
Конференция "Media" » Конвертирование BMP 16 bit или 24 bit > BPM 256 цветов [D6, D7, Win2k, WinXP]
Есть новые Нет новых   [118451   +42][b:0][p:0.001]