Изменение цветового разрешения TBitmap

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Изменение цветового разрешения TBitmap

Сообщение kotompazb » 18.12.2021 11:23:24

Здравствуйте.
Давно меня не было.
Дано. Есть некое битмап-изображение заранее неизвестной глубины (может быть 24bpp, 32bpp...). Фактически используются всего 2 цвета.
Хочется. Преобразовать его в 4bpp. Есть какие-то готовые простые решения. Или преобразование надо делать вручную, ориентируясь на значение Bitmap.PixelFormat?
Спасибо.
Аватара пользователя
kotompazb
постоялец
 
Сообщения: 151
Зарегистрирован: 21.06.2012 13:03:39
Откуда: Novosibirsk, xUSSR

Re: Изменение цветового разрешения TBitmap

Сообщение Alex2013 » 18.12.2021 16:20:04

По идее можно перерисовать через draw...
Чем-то вроде этой процедуры.

Код: Выделить всё
   Function BitmapTest(var TB:TBitmap; Mode:TPixelFormat; F_Free:Boolean=true):Boolean ;
      Var
      CB:TBitmap;
      Begin
       Result:= tb.PixelFormat=mode ;
      if not Result then
      begin
      CB:=TBitmap.Create;
      cb.SetSize(tb.Width,tb.Height);
      cb.PixelFormat:=Mode;
      Cb.Canvas.Draw(0,0,TB);
      if F_Free then tb.free;
      Tb:=CB;
      end
      end;

Правда именно с 4-х и 8-ми битными битмапами есть заморочка с палитрой. Но если битмап нужно просто сохранять в определенном формате то не думаю что это будет проблемой .
Alex2013
долгожитель
 
Сообщения: 2924
Зарегистрирован: 03.04.2013 11:59:44

Re: Изменение цветового разрешения TBitmap

Сообщение Снег Север » 18.12.2021 19:21:51

я бы посмотрел в сторону:
http://galfar.vevb.net/imaging/doc/imaging.html
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2993
Зарегистрирован: 27.11.2007 16:14:47

Re: Изменение цветового разрешения TBitmap

Сообщение kotompazb » 19.12.2021 00:41:57

Alex2013 писал(а):
Код: Выделить всё
   Function BitmapTest(var TB:TBitmap; Mode:TPixelFormat; F_Free:Boolean=true):Boolean ;
      Var
      CB:TBitmap;
      Begin
       Result:= tb.PixelFormat=mode ;
      if not Result then
      begin
      CB:=TBitmap.Create;
      cb.SetSize(tb.Width,tb.Height);
      cb.PixelFormat:=Mode;
      Cb.Canvas.Draw(0,0,TB);
//<-----
      if F_Free then tb.free;
      Tb:=CB;
      end
      end;


К сожалению, после Draw глубина переключается обратно на pf24bit :(

Добавлено спустя 1 минуту 27 секунд:
Снег Север писал(а):я бы посмотрел в сторону:
http://galfar.vevb.net/imaging/doc/imaging.html

Целая либа.

Ладно. Спасиба. Руками будет проще переконвертить, просто было лень.
Аватара пользователя
kotompazb
постоялец
 
Сообщения: 151
Зарегистрирован: 21.06.2012 13:03:39
Откуда: Novosibirsk, xUSSR

Re: Изменение цветового разрешения TBitmap

Сообщение Vadim » 19.12.2021 04:17:36

kotompazb
В исходниках FCL есть пример конвертации - packages/fcl-image/examples/xwdtobmp.pas.
Там преобразование идёт из типа 'xwd", но нам никто не мешает для читателя исходного файла картинки поставить класс "TFPReaderBMP". Строка, относящаяся к Вашей задаче:
Код: Выделить всё
TFWriterBMP(Writer).BitsPerPixel:=32

ставите там нужную битность. Можно поставить и 4 бита и 1. Правда 1 - это будет жесть. :-) Наверное он годится только на ч/б диаграммы...
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Изменение цветового разрешения TBitmap

Сообщение Alex2013 » 19.12.2021 06:28:18

Vadim писал(а):Правда 1 - это будет жесть.

Для распознавания образов после бинаризации самое-то! ( Объем данных сокращается и все жужжит заметно веселее )

ИзображениеИзображение
Зы
BitmapTest вполне рабочая приблуда ( правда гоняю ее в основном между 24 и 32 битами и обратно )
Ее секрет в том что нужно создать новое изображение нужной битности и уже после этого рисовать через Draw. :idea:
Зы
Но если задумал делать "вручную " глянь сюда ..
https://sourceforge.net/projects/tfastdib/
( библиотека FastDIB модуль FConvert - там есть все что угодно ...
Конверсия TBitmap -> TFastDIB; (Встроенная для ВинАпи и работает криво )
Код: Выделить всё
Var
FBmp,TFB:TFastDIB;
B:TBitmap;
FBmp_SD:Pointer;
...
Begin
  FBmp:=TFastDIB.Create;
  FBmp.SetSize(B.Width,B.Height,24);
  FBmp_SD:=FBmp.Bits;
  BitmapTest(b,pf24bit);
with b.RawImage do //FBmp.Bits:=Pointer(Data);
    Move(Data^,FBmp.Bits^,DataSize);
end;

Обратно FBmp -> b
Код: Выделить всё
b.BeginUpdate;
with b.RawImage do Move(FBmp.Bits^,Data^,DataSize);
b.EndUpdate;
FBmp.Bits:=FBmp_SD;

)
Alex2013
долгожитель
 
Сообщения: 2924
Зарегистрирован: 03.04.2013 11:59:44


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11

Рейтинг@Mail.ru