Загрузка bmp

Вопросы программирования на Free Pascal, использования компилятора и утилит.

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

Mavlyudov
новенький
Сообщения: 57
Зарегистрирован: 24.01.2010 19:35:23

Загрузка bmp

Сообщение Mavlyudov »

Здравствуйте,
Есть ли возможность в FreePascal загрузки bmp файла?
Переделываю программу, написанную на Delphi. Суть программы в градиентной заливке нецветного файла.
Я использовал функции переменные типа TBitMap и TMemoryStream (см. кусок кода ниже). Чем их можно заменить, не прибегая к Lazarus?
Предполагается, что программа будет загружать Bmp файл, работать с ним и записывать измененный файл на диск.

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

var
S:TMemoryStream;
TempBitMap:TBitMap;
..........
 TempBitMap:=TBitmap.Create;
 TempBitMap.PixelFormat:=pf24bit;
 TempBitMap.Width:=W;
 TempBitMap.Height:=H;

  S:=TMemoryStream.Create;
  S.LoadFromFile('Test.bmp');
  S.Position:=0;
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

TempBitMap.LoadFromFile('Test.bmp'); в помощь! :wink:
(или TempBitMap.LoadFromStream(Stream) - если есть необходимость загрузить из потока.)
https://wiki.freepascal.org/Developing_with_Graphics/ru
Mavlyudov
новенький
Сообщения: 57
Зарегистрирован: 24.01.2010 19:35:23

Сообщение Mavlyudov »

TempBitMap.LoadFromFile('Test.bmp'); такого нету, пишет "Error: identifier idents no member "LoadFromFile"".
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Mavlyudov писал(а):TempBitMap.LoadFromFile('Test.bmp'); такого нету, пишет "Error: identifier idents no member "LoadFromFile"".
В таком случае проверьте:
- У Вас TBitMap - это класс, не record?
- Является ли этот класс взятым из модуля Graphics?
Класс Graphics.TBitMap совершенно точно и неоспоримо является наследником класса TGraphic, у которого этот метод есть.
Mavlyudov
новенький
Сообщения: 57
Зарегистрирован: 24.01.2010 19:35:23

Сообщение Mavlyudov »

Vadim
Модуль Graphics есть только в Lazarus вроде как
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Mavlyudov писал(а):Модуль Graphics есть только в Lazarus вроде как
Так это же прекрасно! Я бы даже сказал - просто восхитительно... ;-) Раз Вы переписываете дельфийскую программу, то запустив Lazarus попадёте в знакомый Вам интерфейс, который, вдобавок, поможет всякими разными подсказками.
Или Вы Lazarus люто ненавидите?
Mavlyudov
новенький
Сообщения: 57
Зарегистрирован: 24.01.2010 19:35:23

Сообщение Mavlyudov »

Vadim
Без него хочу сделать. Чисто консольную программу, используя только fpc
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

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

Сообщение Vadim »

Mavlyudov писал(а):Без него хочу сделать. Чисто консольную программу, используя только fpc
Т.е. "не хочу, чтобы было удобно, хочу заморочится..."? :-D
Ну тогда, если чистая девственная консоль - "Где_там_у_Вас_Исходники_FPC/packages/fcl-image/" - практически все общераспространённые форматы рисунков, там же и примеры, как работать.
Mavlyudov
новенький
Сообщения: 57
Зарегистрирован: 24.01.2010 19:35:23

Сообщение Mavlyudov »

Vadim
Да, именно заморочиться.

Alex2013
Подскажите пожалуйста,как поменять палитру в файле без использования Scanline?

Допустим, я загрузил bmp в двумерный массив.
До этого палитра менялась так:

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

   
Var
  Color:Byte;
  S:TMemoryStream;
type
	RGB=Record
	b,g,r: Byte;
	End;
type
  TPixels=Array[0..0] of RGB;
	PPixels= ^TPixels;
var
  Row: PPixels;

Palette: Array[0..255] of RGB;
..................................................
For Y:=0 To H-1 Do
    Begin
      Row:=TempBitMap.Scanline[Y];
      For X:=0 To W-1 Do
       begin
       S.ReadBuffer(Color,1);
        Row^[X]:=Palette[Color];
       end;
    End;

Как сделать тоже самое, без scanline, TBitmap, TMemoryStream и прочего, имея только массив с картинкой?
Сквозняк
энтузиаст
Сообщения: 1159
Зарегистрирован: 29.06.2006 22:08:32

Сообщение Сквозняк »

Mavlyudov писал(а):Как сделать тоже самое, без scanline, TBitmap, TMemoryStream и прочего, имея только массив с картинкой?
Можешь сам править байты циклом, но проблема в том, что придётся разбираться какой цвет байт обозначает в реальности. Когда-то так конвертировал bmp в другой формат и чтобы конвертация происходила правильно, приходилось каждый раз создавать bmp в одном и том же редакторе. Если картинка была создана в другом, то по умолчанию в ней байты обозначали другие цвета. Вот потому обычно используют графические библиотеки, чтобы не париться с нюансами графических форматов, с ними ты сможешь легко и с png работать. Поиск по исходникам fpc показывает, что в нём есть модули fpreadbmp и fpwritebmp там должно быть что-то близкое к нужному.
Mavlyudov
новенький
Сообщения: 57
Зарегистрирован: 24.01.2010 19:35:23

Сообщение Mavlyudov »

Сквозняк
Можно пример того, как править байты?
Сквозняк
энтузиаст
Сообщения: 1159
Зарегистрирован: 29.06.2006 22:08:32

Сообщение Сквозняк »

Mavlyudov писал(а):Сквозняк
Можно пример того, как править байты?
Считываешь из первого массива байты пикселя, преобразовываешь их в другой формат и записываешь во второй массив. А вот чем отличаются байты в форматах, тебе нужно выяснить самому ковыряясь в документации, исходниках или экспериментальным путём провести реверсинжиниринг. Например, делаешь файл с малиновым цветом в разных форматах, а потом смотришь, в чём отличие в байтах. Потом тоже самое делаешь для другого цвета. Я так для 16 цветного бмп делал, мне проще было :mrgreen: Непонятно, почему тебе вдруг понадобилось всё делать самому, отказываясь от готовых решений. Размер бинарника пытаешься уменьшить?

Добавлено спустя 8 минут 18 секунд:
Вообще, можно всю палитру бмп впихнуть в один или несколько файлов, по пикселю на цвет, конвертировать, а потом написать программу, которая составит таблицы соответствия цветов. Как есть массивы перекодирования букв в разные кодировки, только для картинок сделать. Только потом эти таблицы оптимизировать, чтобы получить более компактные формулы.

Добавлено спустя 53 секунды:
Если ты для древней программы, у которой мало цветов в палитре было, делаешь, то там и небольшая таблица в итоге выйдет.
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Я обычно конвертирую через Canvas.Draw().Это проще . Но нужно учитывать что все "лоу колор"(от одно до шестнадцати битных ) режимы используют палитру . То есть некий 101 -й цвет в 8-ми битном режиме это просто индекс в таблице палитры, который может отображаться как угодно.(Еще есть стандартная палитра эмулирующая что-то непонятное вроде 2:2:2 RGB + 16 стандартных цветов и 16-гадиента серого , но ее никто не использует )
Изображение
То есть конвертируя из 24-х или 32-х битного в 8-ми битный нужно еще и палитру создавать ( которая в случае многоцветной фотки будет весьма приблизительной и потребует для своего создания целый "вагон математики" ) обратное преобразование проще (цвет из палитры, банально будет заменять индекс цвета в растре ) Но это еще более менее простой случай а вот фокусы с 16,4,2 -х битными режимами это местами вообще полный берд ! (Например стандартных 16-рарядных режимов есть две штуки на 32 768 и 65 536 цветов, причем первый на самом деле 12-ти битный, но памяти использует ровно столько-же как и второй, а еще есть 15-разрядный (5:5:5) с битом альфа канала и как-бы полноценный 16-разрядный (5:6:5) с большей глубиной зеленого (при стандартной поллитре именно ее используют 3д акселераторы для 16-разрядых режимов но в принципе 16-ти битная поллитра может работать так-же как в 8-ми битная ). )
Аватара пользователя
Vlad04
новенький
Сообщения: 80
Зарегистрирован: 11.12.2007 20:11:19
Откуда: Караганда. Казахстан

Сообщение Vlad04 »

Mavlyudov писал(а):Сквозняк
Можно пример того, как править байты?
У TBitmap есть свойство RawImage, у которого есть свойство Data - указатель на начало массива байт (TBitmap.RawImage.Data)
Ответить