Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.09.15;
Скачать: CL | DM;

Вниз

Кто знает формат .bmp, помогите.   Найти похожие ветки 

 
выарп   (2003-08-23 19:49) [0]

Хочу отобразить .bmp файл на форме (ни какой практической цели этим не преследую).
Но вот не получается. Цвета не всегда (не для всякой бэ-эм-пэшки) правильно отображаются. Объясните, пожалуйста, что не так.

program Project1;
uses
Forms,
Unit1 in "Unit1.pas" {Form1};
{$R *.RES}
begin
assign(bmpfile, "file.bmp");
reset(bmpfile,1);
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
Close(bmpfile);
end.
//----------------
unit Unit1;
...
var
...
bmpfile: file;
buff: array[1..3072] of char;
numread, i: integer;
bmpwidth, bmpheight, x, y: integer;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
blockread(bmpfile, buff, sizeof(buff));
bmpwidth:=ord(buff[19])+ord(buff[20])*256+ord(buff[21])*256*256+ord(bu ff[22])*256*256*256;
bmpheight:=ord(buff[23])+ord(buff[24])*256+ord(buff[25])*256*256+ord(b uff[26])*256*256*256;
seek(bmpfile, 54);
x:=1; y:=bmpheight; i:=0;
repeat
blockread(bmpfile, buff, sizeof(buff), numread);
repeat
canvas.Pixels[x,y]:=ord(buff[1+i*3])+ord(buff[2+i*3])*256+ord(buff[3+i *3])*256*256;
inc(i);
inc(x);
if x>bmpwidth then begin x:=1; inc(y,-1) end;
until i=1024;
i:=0;
until numread=0;
end;


 
shark ©   (2003-08-23 19:58) [1]

Так ты просто в TBitmap загрузи .


 
выарп   (2003-08-23 20:12) [2]

Я просто хочу понять, что не так?


 
выарп   (2003-08-23 20:41) [3]

Забыл сказать, что бэ-эм-пэшки 24-битные.


 
Palladin ©   (2003-08-23 22:41) [4]

хм, это интересно...
а в каком смысле "не совсем так"? Совсем не так или похоже?

в этом случае можно провести экспиримент, загрузить BMP где цвета не так в TBitmap и прочитать значение палитры, после - сравнить с той которую читаешь ты и посмотреть разницу, только так можно понять что не так :)


 
wl ©   (2003-08-24 01:57) [5]

Задай свой вопрос не в "Потрепаться" а в "WinAPI", плиз(спешиал фо ми)


 
DrPass ©   (2003-08-24 12:28) [6]

Просто не зря данные в bmp-файле начинаются не сначала. Первые блоки - это информация о палитре. Почитать бы доку кое-кому сперва


 
выарп   (2003-08-24 16:35) [7]

>DrPass © (24.08.03 12:28) [6]
>Просто не зря данные в bmp-файле начинаются не сначала. Первые
>блоки - это информация о палитре. Почитать бы доку кое-кому сперва

Я-то как раз читал:
"The color table is not present
for bitmaps with 24 color bits because each pixel is represented by 24-bit
red-green-blue (RGB) values in the actual bitmap data area."


 
выарп   (2003-08-24 16:40) [8]

>DrPass © (24.08.03 12:28) [6]
>Просто не зря данные в bmp-файле начинаются не сначала. Первые
>блоки - это информация о палитре. Почитать бы доку кое-кому сперва

Ты бы лучше мой код прочитал и сказал, что не так?


 
Ketmar ©   (2003-08-24 17:00) [9]

всё не так.


 
выарп   (2003-08-24 17:43) [10]

>Ketmar © (24.08.03 17:00) [9]
>всё не так.

Намекни на самые главные ошибки.


 
Ketmar ©   (2003-08-24 18:33) [11]

начиная с "var" и дальше -- всё сплошная ошибка. за такой код убивают. из шотгана. в живот.


 
Palladin ©   (2003-08-24 18:38) [12]

лучше в голову


 
выарп   (2003-08-24 19:17) [13]

Насчет кода - так я ведь не сочинение писал, а просто хотел понять формат .bmp (цель знаете ли другая).
Спасибо, что помогли; действительно, МАСТЕРА.

з.ы. вы случайно не в олимпийской сборной по стрельбе?


 
otido ©   (2003-08-24 19:19) [14]

честно скажу, не знаю ответа на вопрос, но по-моему слишком жестковато относятся... Вай?


 
Ketmar ©   (2003-08-24 19:32) [15]

>#12
в голову -- это сразу. а в живот -- долго и мучительно. шоб знал, как оно.

>#13
хоть трижды "не сочинение". ты дома тоже мимо сортира ходишь, потому что "всё равно никто не видит"?

>#14
сказали же: за "код".


 
выарп   (2003-08-24 19:40) [16]

>Ketmar © (24.08.03 19:32) [15]
>#13
>хоть трижды "не сочинение". ты дома тоже мимо сортира ходишь,
>потому что "всё равно никто не видит"?

Убедил. Покажи, как надо. А потом я пойду искать шотган.


 
otido ©   (2003-08-24 19:42) [17]

... и сам застрелюсь, да?))


 
выарп   (2003-08-24 19:46) [18]

>... и сам застрелюсь, да?))

Сначала по коду Ketmar`а посмотрю, чей живот действительно его достоин.


 
hhhjjjkkk   (2003-08-24 19:54) [19]

TBitmap.LoadFromFile


 
выарп   (2003-08-24 20:01) [20]

>hhhjjjkkk (24.08.03 19:54) [19]
>TBitmap.LoadFromFile

Ну и что? Ты понял формат .bmp? Или мне объяснил этим?


 
wicked ©   (2003-08-24 20:08) [21]

2 выарп
млин.... для начала почитай в мсдн про BITMAPFILEHEADER, BITMAPINFO, BITMAPINFOHEADER... тогда причеши свой код, а потом мы увидим, будут ли еще у тебя вопросы....


 
dkjfhgjhfkj   (2003-08-24 20:12) [22]

procedure TFastDIB.LoadFromFile(FileName:string);
var
i: DWord;
Buffer: Pointer;
bmInfo: TBMInfo;
hFile: Windows.HFILE;
fBits,xSize,fSize: DWord;
begin
hFile:=CreateFile(PChar(FileName),GENERIC_READ,FILE_SHARE_READ,nil,OPE N_EXISTING,0,0);
fSize:=GetFileSize(hFile,nil);
xSize:=fSize;
if xSize>1078 then xSize:=1078;
GetMem(Buffer,1078);
ReadFile(hFile,Buffer^,xSize,i,nil);
fBits:=LoadHeader(Buffer,bmInfo);
SetSizeIndirect(bmInfo);
SetFilePointer(hFile,fBits-xSize,nil,FILE_CURRENT);
if(bmInfo.Header.Compression=1)or(bmInfo.Header.Compression=2)then xSize:=PDWord(Integer(Buffer)+2)^-fBits else
if fSize-fBits > Size then xSize:=Size else xSize:=fSize-fBits;
if(bmInfo.Header.Compression=0)or(bmInfo.Header.Compression=3)then
ReadFile(hFile,Bits^,xSize,i,nil)else
begin
ReAllocMem(Buffer,xSize);
ReadFile(hFile,Buffer^,xSize,i,nil);
if bmInfo.Header.Compression=1 then DecodeRLE8(Self,Buffer) else DecodeRLE4(Self,Buffer);
end;
CloseHandle(hFile);
FreeMem(Buffer);
end;

function LoadHeader(Data:Pointer;var bmInfo:TBMInfo):Integer;
var
i: Integer;
begin
if PDWord(Ptr(Integer(Data)+14))^=40 then
Move(Ptr(Integer(Data)+14)^,bmInfo,SizeOf(bmInfo))
else if PDWord(Ptr(Integer(Data)+14))^=12 then
with PBitmapCoreInfo(Ptr(Integer(Data)+14))^ do
begin
FillChar(bmInfo,SizeOf(bmInfo),0);
bmInfo.Header.Width:=bmciHeader.bcWidth;
bmInfo.Header.Height:=bmciHeader.bcHeight;
bmInfo.Header.BitCount:=bmciHeader.bcBitCount;
if bmciHeader.bcBitCount<=8 then
for i:=0 to (1 shl bmciHeader.bcBitCount)-1 do
bmInfo.Colors[i]:=PFColorA(@bmciColors[i])^;
end;
Result:=PDWord(Ptr(Integer(Data)+10))^;
end;


 
выарп   (2003-08-24 20:19) [23]

>wicked © (24.08.03 20:08) [21]
Читал. Хочешь я тебе каждый байт заговка 24 bit .bmp объясню.

>dkjfhgjhfkj (24.08.03 20:12) [22]
Читаю...


 
wicked ©   (2003-08-24 20:35) [24]

2 выарп
плохо читал....
гляди пример на Билдере:

TMemoryStream * ms = new TMemoryStream();
ms->LoadFromFile("<my bmp file>");
ms->Position = 0;
LPBITMAPFILEHEADER bfh = (LPBITMAPFILEHEADER) ms->Memory;
LPBITMAPINFO bi = (LPBITMAPINFO)((LPBYTE)ms->Memory + sizeof(BITMAPFILEHEADER));
StretchDIBits(Handle, 0, 0, Width, Height,
0, 0, bi->bmiHeader.biWidth, bi->bmiHeader.biHeight,
((LPBYTE)ms->Memory + bfh->bfOffBits), bi, DIB_RGB_COLORS, SRCCOPY);
delete ms;


переведи его на паскаль, попробуй.... тогда спрашивай...

ЗЫ минусом данного кода есть то, что он не читает полуосевый .bmp... но кто сейчас про это вспомнит?... ;)


 
wicked ©   (2003-08-24 20:44) [25]

сори...
вот это:

> StretchDIBits(Handle, 0, 0, Width, Height,
> 0, 0, bi->bmiHeader.biWidth, bi->bmiHeader.biHeight,
> ((LPBYTE)ms->Memory + bfh->bfOffBits), bi, DIB_RGB_COLORS,
> SRCCOPY);

надо читать как

StretchDIBits(Handle, 0, 0, ClientWidth, ClientHeight,
0, 0, bi->bmiHeader.biWidth, bi->bmiHeader.biHeight,
((LPBYTE)ms->Memory + bfh->bfOffBits), bi, DIB_RGB_COLORS,
SRCCOPY);

;)


 
cyborg ©   (2003-08-24 22:17) [26]


//bfType WORD Содержит ASCII-коды символов «BM»
//bfReserved1 WORD Всегда равен 0
//bfReserved2 WORD Всегда равен 0
//bfOffBits DWORD Смещение в байтах от начала файла до графических данных
PBitmapFileHeader = ^TBitmapFileHeader;
TBitmapFileHeader = packed record
bfType: Word;
bfSize: DWORD;
bfReserved1: Word;
bfReserved2: Word;
bfOffBits: DWORD;
end;

//biSize DWORD Размер данной структуры в байтах
//biWidth DWORD Ширина растра в пикселях
//biHeight DWORD Высота растра в пикселях
//biPlanes WORD Всегда равен 1
//biBitCount WORD Количество битов на пиксель
//biCompression DWORD Тип сжатия: 0 = отсутствует, 1 = RLE-8, 2 = RLE-4
//biSizeImage DWORD Размер растра в байтах
//biXPelsPerMeter DWORD Количество пикселей на метр по горизонтали
//biYPelsPerMeter DWORD Количество пикселей на метр по вертикали
//biClrUsed DWORD Количество использованных цветов
//biClrImportant DWORD Количество значащих цветов
PBitmapInfoHeader = ^TBitmapInfoHeader;
TBitmapInfoHeader = packed record
biSize: DWORD;
biWidth: Longint;
biHeight: Longint;
biPlanes: Word;
biBitCount: Word;
biCompression: DWORD;
biSizeImage: DWORD;
biXPelsPerMeter: Longint;
biYPelsPerMeter: Longint;
biClrUsed: DWORD;
biClrImportant: DWORD;
end;

tagRGBQUAD = packed record
rgbBlue: Byte;
rgbGreen: Byte;
rgbRed: Byte;
rgbReserved: Byte;
end;

PBitmapInfo = ^TBitmapInfo;
TBitmapInfo = packed record
bmiHeader: TBitmapInfoHeader;
bmiColors: array[0..0] of TRGBQuad;
end;


 
выарп   (2003-08-25 10:47) [27]

>cyborg © (24.08.03 22:17) [26]
Спасибо. Но я как бы это знаю. Я хотел было это же wicked`у писать.
Только вот беру я два .bmp файла с совершенно одинаковыми заголовками, один из них отображается корректно, а другой нет.
Может я действительно даун?
В своей программе я сначала считываю из .bmp первые 3072 байта в массив buff (по-любому весь заголовок войдет:)
blockread(bmpfile, buff, sizeof(buff));
Первые два байта меня (пока) не интересуют, я и так знаю, что это bmp. Следующие 4 байта (размер файла) мне тоже по барабану. Пропускаем 4 резервных байта.
Оба файла брались с заголовками в 54 байта, поэтому следующие 8 байтов мне тоже не интересны.
Далее, я читаю размеры картинки:
bmpwidth:=ord(buff[19])+ord(buff[20])*256+ord(buff[21])*256*256+ ord(bu ff[22])*256*256*256;
bmpheight:=ord(buff[23])+ord(buff[24])*256+ord(buff[25])*256*256 +ord(b uff[26])*256*256*256;
Следующие два байта - значение 01 00.
Потом (24bit) - 18 00
Сжатие у обеих картинок: 00 00 00 00
Размер растра: 00 00 00 00 - в обеих так прописано.
количество пикселей на метр: 12 0B 00 00 - и по горизонтали и по вертикали (но мне-то это на кой?).
Далее в заголовке сплошные нули.

Потом, начиная с 55 байта, пошли данные о цвете пикселей. Их я и читаю (т.к. bmp 24bit, rgbReserved - отсутствует):

seek(bmpfile, 54);
x:=1; y:=bmpheight; i:=0;
repeat
blockread(bmpfile, buff, sizeof(buff), numread);
repeat
canvas.Pixels[x,y]:=ord(buff[1+i*3])+ord(buff[2+i*3])*256+ord(buff[3+i *3])*256*256;
inc(i);
inc(x);
if x>bmpwidth then begin x:=1; inc(y,-1) end;
until i=1024;
i:=0;
until numread=0;


 
[lamer]Barmaglot ©   (2003-08-25 14:56) [28]

Лень смотреть код...
1. По длинне слова выравниваешь?
2. Размеры изображений в студию плиз...


 
Ketmar ©   (2003-08-25 16:15) [29]

>#16
запросто. 50 USD. забесплатно у меня и более интересные дела есть. окромя создания очередного самоката.

>#28
нихрена там не ровняют, видно же, что нет этого кода.


 
otido ©   (2003-08-25 16:38) [30]

2 Ketmar (#29)
"А вам слабо?!"


 
Ketmar ©   (2003-08-25 17:09) [31]

>#30
угу. слабо. зачем?


 
otido ©   (2003-08-25 17:12) [32]

хм... а просто так... а то 50 уёв..... корыстно как-то....


 
Ketmar ©   (2003-08-25 17:14) [33]

с бескорыстием -- не ко мне. бескорыстно я могу только застрелить. и то если просящий предоставит оружие и боеприпасы.


 
otido ©   (2003-08-25 17:21) [34]

во блин....


 
cyborg ©   (2003-08-25 17:55) [35]

Вот из своего конвертера BMP24to16 повырезал код, может чего забыл:

...
TYPE
TSrcPicture = array[0..0] of byte;
VAR
BitmapFileHeader : TBitmapFileHeader;
BmpInfo : TBitmapInfo;
SrcSize : Cardinal;
SrcFile : File;
SrcPicture : Pointer;

...
//Функция получает адрес с данными пикселей:
Function ProcessPicture(Var SrcPicture : Pointer;
BPP: byte;W,H : Cardinal; Palette : Pointer) : boolean;
Var
Size : Cardinal;
I : Integer;
R,G,B : Byte;
begin
Result:=false;
Size:=(W*H*BPP) div 8;
Case BPP of
24 : begin
//Тут получай свои пиксели:
for I:=0 to (Size div 3)-1 do
begin
R:=TSrcPicture(SrcPicture^)[I*3];
G:=TSrcPicture(SrcPicture^)[I*3+1];
B:=TSrcPicture(SrcPicture^)[I*3+2];
end; //for I:=1 to Size do
end;
end;//case BPP
Result:=True;
end;

...

AssignFile(SrcFile,"file.bmp");
Reset(SrcFile,1);
FillChar(BitmapFileHeader,SizeOf(TBitmapFileHeader),0);

if FileSize(SrcFile)>SizeOf(TBitmapFileHeader) then
BlockRead(SrcFile,BitmapFileHeader,SizeOf(TBitmapFileHeader));
//Тут сделай проверку на загловок, если это BMP, то продолжай
...
BlockRead(SrcFile,BmpInfo.bmiHeader,SizeOf(TBitmapInfoHeader));
Seek(SrcFile,BitmapFileHeader.bfOffBits);
//Вычисляется размер для несжатого файла:
SrcSize:=(BmpInfo.bmiHeader.biWidth*BmpInfo.bmiHeader.biHeight*BmpInfo .bmiHeader.biBitCount) div 8;
//Выделение памяти под пиксели картинки:
GetMem(SrcPicture,SrcSize);
ProcessPicture(SrcPicture,
BmpInfo.bmiHeader.biBitCount,
BmpInfo.bmiHeader.biWidth,
BmpInfo.bmiHeader.biHeight,nil);
FreeMem(SrcPicture,SrcSize); SrcPicture:=nil;
CloseFile(SrcFile);
...


Ещё учти то, что высота, вроде, если имеет отрицательное значение, то строки в файле записаны наоборот, т.е. снизу вверх.

Насчёт выделения памяти под заголовок, нужно не с фонаря размеры брать, а точно, ты же не на картошку поехал :)


 
cyborg ©   (2003-08-25 18:03) [36]

Сейчас просмотрел, главное забыл :)
после
GetMem(SrcPicture,SrcSize);
нужно вставить
BlockRead(SrcFile,SrcPicture^,SrcSize);


 
выарп   (2003-08-25 19:42) [37]

to cyborg ©
Для твоего кода, тоже bmp-ки не верно отображаются (как у меня).
Я понимаю, что мало чего смыслю в программировании, но
тут мелькнула мысль: .icm как-нибудь может влиять на отбражаемые цвета?
В любом случае, вот мои bmp-ки с твоим кодом:
http://www.sinor.ru/~namenlos/bmp.zip (23,6 КБ)


 
cyborg ©   (2003-08-25 21:01) [38]

Поменяй местами R и B цвета.


 
выарп   (2003-08-26 08:55) [39]

>cyborg © (25.08.03 21:01) [38]
Спасибо!!!

А ларчик просто открывался...



Страницы: 1 вся ветка

Текущий архив: 2003.09.15;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.033 c
1-48498
Calm
2003-09-02 17:13
2003.09.15
Корректно ли создать в методе TThread.Execute VCL-компоненты?


14-48709
PVOzerski
2003-08-19 11:12
2003.09.15
Какой сотовый телефон выбрать


14-48730
Dmitriy O.
2003-08-26 11:57
2003.09.15
Как приготовить яйцо в микроволновке


14-48753
Тролль
2003-08-26 18:19
2003.09.15
Multimedia API


1-48526
elf
2003-09-02 13:37
2003.09.15
savedialog1.filename