Bitmap.SaveToFile и формат BMP-файла

Вопросы программирования и использования среды Lazarus.

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

Bitmap.SaveToFile и формат BMP-файла

Сообщение FreeBSD-ier » 10.12.2010 12:03:18

ОС - Windows XP SP3
IDE - Lazarus 0.9.28.2 бета + winCE

Все банально - на форме Image. На FormCreate прописано :

var SelfPath: string;
TmpBmp: TBitMap;
begin
SelfPath := trim( ExtractFilePath(ParamStr(0)) );
Image1.Picture.Bitmap.LoadFromFile( SelfPath+'\BitMapIN.bmp' );
Application.ProcessMessages;
Image1.Picture.Bitmap.SaveToFile( SelfPath+'\BitMapOUT.bmp' );
Application.ProcessMessages;
Image1.Picture.LoadFromFile( SelfPath+'\JpegIN.jpg' );
Application.ProcessMessages;

TmpBmp := TBitMap.Create;
TmpBmp.PixelFormat := pf16bit;
TmpBmp.Assign(Image1.Picture.Graphic);
TmpBmp.SaveToFile( SelfPath+'\JpegOUT.bmp' );
Application.ProcessMessages;
TmpBmp.Free;

end;

BitMapIN.bmp - картинка с машинкой, 480x272 пикселей 16 бит. Размер файла 261 176 байт (кратный 4-ём)
JpegIn.jpg - таже самая машинка но конвертированая фотошопом из BMP в Jpeg.

После компиляции под Win32 получаю : BitMapOUT = BitMapIN (не считая недостающих 2-ух $00 байт в конце, которые в исходном битмапе были добавлены фотошопом для кратности 4). А вот JpegOUT - все время 32 битный, не взирая на PixelFomat...

Отсюда первый вопрос - а работает ли корректно PixelFormat в лазаре??? Если да - то как его надо применять?..

Второй вопрос : Все тоже самое, но код на FormCreate чуть изменен:

var SelfPath: string;
TmpBmp: TPicture;
begin
SelfPath := trim( ExtractFilePath(ParamStr(0)) );
Image1.Picture.Bitmap.LoadFromFile( SelfPath+'\BitMapIN.bmp' );
Application.ProcessMessages;
Image1.Picture.Bitmap.SaveToFile( SelfPath+'\BitMapOUT.bmp' );
Application.ProcessMessages;
Image1.Picture.LoadFromFile( SelfPath+'\JpegIN.jpg' );
Application.ProcessMessages;

TmpBmp := TPicture.Create;
TmpBmp.Bitmap.PixelFormat := pf16bit;
TmpBmp.Bitmap.Assign(Image1.Picture.Graphic);
TmpBmp.Bitmap.SaveToFile( SelfPath+'\JpegOUT.bmp' );
Application.ProcessMessages;
TmpBmp.Free;
end;

То есть динамически создаем не BitMap, а Picture (т.к. при компиляции под WinCE для arm лазарь не хочет создавать битмапы).
Компилирую все это дело под WinCE и запускаю на навигаторе ACER p610 c WinCE 5.0.
В итоге получаем - BitMapOUT = BitMapIN (не считая недостающих 2-ух $00 байт в конце, которые в исходном битмапе были добавлены фотошопом для четности).
JpegOUT - 16 битный, но его размер 261 186 (не кратный 4-ем), добавлены 10 байт в заголовок DIB, полностью другое содержимое файла (байтики) - что свидетельствует о другой используемой палитре, и этот BMP невозможно потом загрузить ни в один компонент программы под WinCE. То есть : при попытке открыть его на WinCE стандартными средствами ОС - он отрывается. Если попытаться загрузить его в программу написанную на лазаре, например банально - Picture.LoadFromFile() или Picture.Bitmap.LoadFromFile() (перепробовал любые варианты) - прога тутже вываливается в ошибку - Bus error, misaligned data - что, на сколько я понимаю свидетельствует о том, что Arm-процессор читает по 4 байта, а в этом файле данные не кратны 4.

Отсюда второй, третий и четвертый вопросы:

2. Правильно ли я трактовал ошибку про Bus error и Misaligned data?
3. Почему при всем при этом нормально загружается BitMapOUT, у которого размер 261 174 - который также не кратный 4-ём (хотя, на сколько я понимаю, данные о цветах пикселей в нем все равно (как и в JpegOUT) должны быть кратными - 480*272*2 = 261120; 261120 div 4 = 0).
4. Почему стандартные средства ОС могут отрыть и прочитать JpegOUT, а прога под лазарем вываливает в ошибку? Как прочитать и загрузить этот файл???

PS: Перепробовал уже все известные мне способы сохранения и открытия - ничего не помогает. Все равно вываливается в ошибу...
PS2: Пробовал создавать отдельно заголовок BMP и дополнять его нужными байтами, попиксельно читая канву JPEG-а - сработало нормально, получился нормальный бмпшник, но это очень долго...
PS3: Сохранять картинку надо именно в BMP формате.
FreeBSD-ier
незнакомец
 
Сообщения: 5
Зарегистрирован: 10.12.2010 10:54:54

Re: Bitmap.SaveToFile и формат BMP-файла

Сообщение Sergei I. Gorelkin » 10.12.2010 13:06:32

Вообще говоря, PixelFormat нужно изменять после Assign, потому что Assign - это тупое присваивание, затирающее все свойства объекта назначения.
Если не заработает и так - можно делать вывод, что pixelFormat работает некорректно.

Bus error, misaligned data означают попытки чтения 32-битных слов с адресов, не кратных 4, или 16-битных слов с адресов, не кратных 2. Только файл тут ни при чем (т.к. стандартыми средствами он нормально открывается), это баг именно в lazarus-программе (правда, сложно сказать, где именно - в fcl-image или в LCL). Пиши багрепорт с приложением проблемного файла и куска своей программы, достаточного для воспроизведения проблемы...
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Bitmap.SaveToFile и формат BMP-файла

Сообщение FreeBSD-ier » 10.12.2010 13:44:39

PixelFormat не работает ни после Assign ни перед, вообще нигде :(...
FreeBSD-ier
незнакомец
 
Сообщения: 5
Зарегистрирован: 10.12.2010 10:54:54

Re: Bitmap.SaveToFile и формат BMP-файла

Сообщение Nik » 10.12.2010 14:49:58

FreeBSD-ier писал(а):PixelFormat не работает ни после Assign ни перед, вообще нигде :(...


Если так - то пишите в багтрекер, с примером нерабочего кода.
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров


Вернуться в Lazarus

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

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

Рейтинг@Mail.ru