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

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

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

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

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

Сообщение kotompazb »

Здравствуйте.
Давно меня не было.
Дано. Есть некое битмап-изображение заранее неизвестной глубины (может быть 24bpp, 32bpp...). Фактически используются всего 2 цвета.
Хочется. Преобразовать его в 4bpp. Есть какие-то готовые простые решения. Или преобразование надо делать вручную, ориентируясь на значение Bitmap.PixelFormat?
Спасибо.
Alex2013
долгожитель
Сообщения: 3230
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

По идее можно перерисовать через 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-ми битными битмапами есть заморочка с палитрой. Но если битмап нужно просто сохранять в определенном формате то не думаю что это будет проблемой .
Аватара пользователя
kotompazb
постоялец
Сообщения: 156
Зарегистрирован: 21.06.2012 13:03:39
Откуда: Novosibirsk, xUSSR

Сообщение kotompazb »

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

Целая либа.

Ладно. Спасиба. Руками будет проще переконвертить, просто было лень.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

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

Код: Выделить всё

TFWriterBMP(Writer).BitsPerPixel:=32

ставите там нужную битность. Можно поставить и 4 бита и 1. Правда 1 - это будет жесть. :-) Наверное он годится только на ч/б диаграммы...
Alex2013
долгожитель
Сообщения: 3230
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

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;

)
Ответить